petzval / btferret

Python and C Bluetooth Library
MIT License
126 stars 22 forks source link

Cannot connect to LE node (Unknown Connection Identifier) #9

Closed kahlenberg closed 1 year ago

kahlenberg commented 2 years ago

Hi, I try to establish a communication to my nRF52840 Module. With btferret I can see my device in the list, I can connect to it and can list the characteristics, I can subscribe to notification and I can receive the notification from nRF52840. Everything works as expected.

However, I wrote a minimal code to connect to nRF52840 but the code gives always error: Unknown Connection Identifier My nRF52840 sends advertisement every 200ms. What is wrong in my code? Thanks.

devices.txt:

DEVICE = My Rpi   TYPE = MESH   NODE = 1001   ADDRESS = <bt address of pi> 
DEVICE = CO2 Sensor Module    TYPE = LE     NODE = 1002   ADDRESS = <address of nRF52840>

main.c:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "btlib.h"

int main(int argc, char *argv[])
{
    int retval = 0;
    if (init_blue("devices.txt") == 0) {
        return (0);
    }
    set_print_flag(PRINT_VERBOSE);
    //le_scan();
    set_le_wait(12000); //ms

    retval = connect_node(1002, CHANNEL_LE, 0);

    while (1)
    {
        /* code */
    }

    printf("ret:%d\nDisconnecting everything and exit..\n",retval);

    close_all();

    return (0);
}

Console output:

Initialising...
Device data from devices.txt file
DEVICE = Tunnel Air Quality   TYPE = MESH   NODE = 1   ADDRESS =  <bt address of pi>
DEVICE = CO2 Sensor Module    TYPE = LE     NODE = 2   ADDRESS =  <address of nRF52840>
SEND LE connect to CO2 Sensor Module
  Set [10].. board address reversed 05..E0
< HCI OGF=08 OCF=0D
      0000  01 0D 20 19 60 00 60 00 - 00 00 05 C6 27 97 D0 E0 
      0010  00 18 00 28 00 00 00 11 - 01 00 00 00 00 
> Event 0F = 00 01 0D 20
      0000  04 0F 04 00 01 0D 20 
Timed out waiting for expected packet
< HCI OGF=08 OCF=0E
      0000  01 0E 20 00 
> Event 0E = 01 0E 20 00
      0000  04 0E 04 01 0E 20 00 
Unknown Connection Identifier
> Event 3E = 01 02 40 00 00 00 05 C6 27 97...
      0000  04 3E 13 01 02 40 00 00 - 00 05 C6 27 97 D0 E0 27 
      0010  00 00 00 11 01 00 
STATUS OK
Fail - no handle
This device may have a random board address which changes
Scan for LE devices to find the current address
leconnect: 0
petzval commented 2 years ago

I think it's the node numbers which must match in the devices file and connect_node . Change them to 1 and 2 as below. Node numbers of 1000 and above are automatically allocated to devices found by a scan that are not in devices.txt. Any device in devices.txt can be assigned a node number of your choice, and would normally be 1,2,3,...

DEVICE = My Rpi   TYPE = MESH   NODE = 1   ADDRESS = <bt address of pi> 
DEVICE = CO2 Sensor Module    TYPE = LE     NODE = 2   ADDRESS = <address of nRF52840>

connect_node(2,CHANNEL_LE,0);
petzval commented 2 years ago

I also see that you are getting a random address warning - so this may be the problem. If the nRF is setting a random address, then it cannot be put into devices.txt because it will change every time the server starts. Your code will only work if the address in the devices file is still valid. By coincidence I have been working on a fix for this, so I'll bring the timetable forward and upload a new version 5 within the next day. When it appears, look at documentation sections 3.3 and 3.6 to see the ADDRESS=MATCH_NAME method.

kahlenberg commented 1 year ago

Ok, thank you. Is there any function to get the node number when names is given as parameter? Second question. Is it possible to deactivate all print messages? Because I want to use the library in my code and I don't want to print all information.

petzval commented 1 year ago

Prints can be disabled with: set_print_flag(PRINT_NONE); I have now uploaded a new version that allows LE devices with a random address to be listed in devices.txt. See the Devices (section 3.3) and second code listing in the LE Client (section 3.6) documentation. The devices listing sets the node number that you choose. A scan must be run (no way to avoid this if the address is random). During the scan, when a name match is found, the previously unknown random address is allocated to the node number you listed. If the scan allocates a new device with a node number of 1000 or higher, then it has failed to find a name match - so this should not happen if the DEVICE= name matches the device's advertised name.

kahlenberg commented 1 year ago

Ok, but before updating my library with new version, I try to connect to nRF52840 when I add information in devices.txt. I changed the NODE numbers in devices.txt, 1 for local device, 2 for remote server (nRF52840). But I receive Unknown Connection Identifier error. Here are the connection logs:

SEND LE connect to CO2 Sensor Module
  Set [10].. board address reversed 05..E0
< HCI OGF=08 OCF=0D
      0000  01 0D 20 19 60 00 60 00 - 00 00 05 C6 27 97 D0 E0 // it begins with 00 00
      0010  00 18 00 28 00 00 00 11 - 01 00 00 00 00 
> Event 0F = 00 01 0D 20
      0000  04 0F 04 00 01 0D 20 
Timed out waiting for expected packet
< HCI OGF=08 OCF=0E
      0000  01 0E 20 00 
> Event 0E = 01 0E 20 00
      0000  04 0E 04 01 0E 20 00 
Unknown Connection Identifier
> Event 3E = 01 02 40 00 00 00 05 C6 27 97...
      0000  04 3E 13 01 02 40 00 00 - 00 05 C6 27 97 D0 E0 27 
      0010  00 00 00 11 01 00 
STATUS OK 

But I try to scan and connect with btferret binary and it connects to nRF. I recognized in raw hex data that in my connection try before BT address a byte is 00, in btferret output it is 01. What is this? What should be activated?


SEND LE connect to CO2 Sensor Module
  Set [10].. board address reversed 05..E0
< HCI OGF=08 OCF=0D
      0000  01 0D 20 19 60 00 60 00 - 00 01 05 C6 27 97 D0 E0  // it begins with 00 01, what is 01?
      0010  00 18 00 28 00 00 00 11 - 01 00 00 00 00 
> Event 0F = 00 01 0D 20
      0000  04 0F 04 00 01 0D 20 
> Event 3E = 01 00 40 00 00 01 05 C6 27 97...
      0000  04 3E 13 01 00 40 00 00 - 01 05 C6 27 97 D0 E0 27 
      0010  00 00 00 11 01 00 
Connect OK as LE client
Handle = 0040
kahlenberg commented 1 year ago

Ok, I found it. It is the addrss type. 0: fixed, 1: random. https://github.com/petzval/btferret/blob/main/btlib.c#L4653 I think in previous version, it is not possible to save a device with random address in devices.txt. I will update my library to the new version and test it.

petzval commented 1 year ago

Yes, that's right. It was not possible to list a random address device in devices.txt because it is not possible to know what the address will be. In the new version, a random address device is listed with ADDRESS=MATCH_NAME and a scan will then find the device with the specified DEVICE= name and find the address that way.

petzval commented 1 year ago

I've tried the blinky example on my nRf52840 and it has a random address, but it does not change, even after a new power up. So I have uploaded a new version with an option to list a random address in the devices file, but it must be flagged as RANDOM=UNCHANGED. So now a scan is not required and the connection will be super-quick. See documentation 3.3 and 3.6. But you have to be sure that the random address never changes.

kahlenberg commented 1 year ago

Thank you very much. That was what I need. No need to scan at startup anymore. Yes nRF52840 has always the same "random" address and I couldn't find to make it public.