Closed gregoiregentil closed 2 months ago
The library does not allow a device to be a Classic and LE server at the same time. I have tried the setup and confirmed that A can connect to B and receive notifications, but then B cannot connect to A. The simplest solution is to send data from B to A as notifications, but send from A to B by writing to a B characteristic. So Device A must perform two operations - write to the local characteristic to send a notification to Android, and write to Device B's Receivedata characteristic.
* NOTE Do not call read_notify. The le_server mechanism checks for notifications.
Characteristic definitions:
Device A Node = 1
LECHAR = Notifydata PERMIT = 12 SIZE = 1 UUID = ABCD ; index 0
Device B Node = 2
LECHAR = Notifydata PERMIT = 12 SIZE = 1 UUID = ABCD ; index 0
LECHAR = Receivedata PERMIT = 06 SIZE = 1 UUID = CDEF ; index 1
Device A LE callback code
int le_callback(int clientnode,int operation,int cticn)
{
static int bconnected = 0;
unsigned char buf[256];
if(operation == LE_CONNECT)
{
printf(" %s has connected\n",device_name(clientnode));
if(bconnected == 0)
{
// Connect to Device B and enable Notifydata notifications
connect_node(2,CHANNEL_LE,0);
find_ctics(2);
notify_ctic(2,0,NOTIFY_ENABLE,ncall);
bconnected = 1;
}
if(operation == LE_TIMER)
{
// Send notification to Android
buf[0] = 56;
write_ctic(localnode(),0,buf,1);
// Send data to Device B Receivedata
write_ctic(2,1,buf,1);
}
}
Device A notify callback
int ncall(int node,int cticn,unsigned char *buf,int nread)
{
// Receive notification from Device B
printf("Data = %d\n",buf[0]);
}
Device B LE callback code
int callback(int clientnode,int operation,int cticn)
{
unsigned char buf[8];
if(operation == LE_WRITE)
{
// Receivedata from Device A - cticn should be 1
read_ctic(localnode(),cticn,buf,8);
printf("Data = %d\n",buf[0]);
}
if(operation == LE_TIMER)
{
// Send notifications to Android and Device A
buf[0] = 57;
write_ctic(localnode(),0,buf,1);
}
}
You are not completely getting my requirement: both deviceA and deviceB should be LE servers in order to communicate directly with a native Android app and both devices should communicate together.
I have prepared an example: https://gentil.com/tmp/download.html?d=test-20240905-214900.zip
deviceB is started as LE server only (press 's'). If deviceA is LE client only (press 'c'), no problem. If I start LE server (press 's') after LE client on device A, no problem too.
But if deviceB and deviceA are started as LE server (press 's') and then deviceA is started as LE client (press 'c'), it's not working.
The suggested solution does implement the requirement, but it cannot be done from existing btferret commands, you need to modify the callback code for Device A (le_callback in btferret.c), or write an LE server program from scratch - start with le_server.c. The procedure is as follows:
Thank you.
I have two devices A and B running le_server(). they both include a bunch of characteristics including some notifications.
I have an Android phone using the Android BLE API that connects to both devices A and B at the same time. Obviously, both devices have different MAC address. No problem so far. I want to keep those connections open.
Now, I want to connect A and B together, get the notifications of each other. I might have prefered to connect them through classic but BLE would be OK.
I don't manage to start le_server() and classic_server() simultaneously. Limitation of the library? I'm not sure if the Bluetooth 4.0 chip of my devices A and B can do Bluetooth Classic and BLE at the same time.
I then tried on device A "connect_node(node_deviceB, CHANNEL_LE, 0);". It's flaky. I managed to connect but the discovery is slow and it's not working well. If I do connect_node(node_deviceA) on device B, it says "already connected" but then how could I get the notifications of device A?
In other words, which architecture should I implement to let le_server A and B talk to each other? Thank you in advance.