Closed careylzh closed 1 week ago
You will have to modify btlib.c, it cannot be done from keyboard.c. These are initial suggestions - I cannot guarantee that they will work. There are two problems:
btlib.c Version 17
LINE 6583
multiflag = 0; // HID multi
if((gpar.hidflag & 1) != 0) // (gpar.settings & HID_MULTI) == 0)
{ // check for existing connection
for(k = 1 ; multiflag == 0 && devok(k) != 0 ; ++k)
{
if(dev[k]->conflag == CON_LX)
multiflag = 1;
}
}
LINE 5205
for(devn = 1 ; cp->notify != 0 && devok(devn) != 0 ; ++devn)
{ // search all other devices for notify
dp = dev[devn];
if((dp->conflag & CON_LX) != 0 &&
(gpar.btleflag == 0 || gpar.btlenode == 0 || gpar.btlenode == dp->node))
{ // device devn is connected as LE client
// send notification
Thanks for your fast response. I've tried out the first fix by commenting the check which changes multiflag to 1, but the raspberry pi is still not discoverable after one successful connection.
As for the second point, I am not sure how to modify the block to connect to other devices. seems like I have to fix issue one first.
Yes, there is another issue. Advertising is turned off at line 6663 when an HID device connects. The mesh_on function restarts advertising. Below is what I think is a complete solution, but I have not tested it. It uses the user_function routine to set the node that receives notifications. Call this from your keyboard.c code before starting le_server as below, then as required. The advantage of this code is that the default behavior can be restored, so multiple connections and targeting one phone can be turned on and off, and btlib is still usable for other applications. Modify btlib.c as follows:
in btlib.c Version 17
LINE 6663
if(((gpar.hidflag & 1) == 0 && (gpar.meshflag & MESH_W) != 0) ||
user_function(0,1,0,0,NULL,NULL) != 0)
mesh_on();
LINE 6583
multiflag = 0; // HID multi
if((gpar.hidflag & 1) != 0) // (gpar.settings & HID_MULTI) == 0)
{ // check for existing connection
for(k = 1 ; multiflag == 0 && devok(k) != 0 ; ++k)
{
if(dev[k]->conflag == CON_LX && user_function(0,1,0,0,NULL,NULL) == 0)
multiflag = 1;
}
}
LINE 5205
for(devn = 1 ; cp->notify != 0 && devok(devn) != 0 ; ++devn)
{ // search all other devices for notify
dp = dev[devn];
if((dp->conflag & CON_LX) != 0 &&
(user_function(0,1,0,0,NULL,NULL) == 0 || dp->node == user_function(0,1,0,0,NULL,NULL)) &&
(gpar.btleflag == 0 || gpar.btlenode == 0 || gpar.btlenode == dp->node))
{ // device devn is connected as LE client
// send notification
LINE 14404
int user_function(int n0,int n1,int n2,int n3,unsigned char *dat0,unsigned char *dat1)
{
static int activenode = 0;
if(n1 == 0)
activenode = n0;
return(activenode);
}
IN keyboard.c
Send notifications to node 4 only
*** NOTE *** must be called before le_server
user_function(4,0,0,0,NULL,NULL);
Send notifications to node 7 only
user_function(7,0,0,0,NULL,NULL);
Restore default behaviour (one HID only)
user_function(0,0,0,0,NULL,NULL);
Whoops! The line 6663 modification should be as follows:
LINE 6663
if(((gpar.hidflag & 1) == 0 && (gpar.meshflag & MESH_W) != 0) ||
user_function(0,1,0,0,NULL,NULL) != 0)
mesh_on();
Thanks for this, there is some progress :)
With user_function(4,0,0,0,NULL,NULL);
or user_function(7,0,0,0,NULL,NULL);
before calling le_server
in keyboard.c, I am now able to connect 2 android phones to my rpi. However, none of the keyboard inputs are received on any of the connected devices, even though the devices recognise the rpi as a HID device.
You need to call user_function with the node number of the target phone. There are two approaches:
user_function(4,0,0,0,NULL,NULL); // any non-zero number
le_server(lecallback,0);
close_all();
return(1);
}
int lecallback(int clientnode,int op,int cticn)
{
int n;
static char hello[8] = { "Hello\n"}; // \n = Enter
if(op == LE_CONNECT)
{
printf("Connected OK. Key presses sent to client. ESC stops server\n");
printf("F10 sends Hello plus Enter\n");
user_function(clientnode,0,0,0,NULL,NULL); /********* ADD THIS ******/
}
Thank you! I tried method 2 above, and have achieved exactly what I needed to do at the start of this post.
Archiving my code here for anyone who is interested in future: https://github.com/careylzh/btferret/commit/051530957e3576c60fd3d3f1f8c829f616131228
Context: I chose the values 1000 and 1001 for clientnode
after testing and noticing that my RPi assigns the values 1000+ for clientnode
upon successful connection.
Also modified the code to use F10 to switch. Will close this thread. Thanks @petzval! 🙏
Hi there, thanks so much for your contribution, I am able to run
keyboard.c
on rpi4 (raspbian OS headless) and send keystrokes to my android phone.However, I am trying to modify the script such that the code allows 2 phones to be connected to the rpi at the same time, and
Alt+Tab
changes the sending of the keystroke from one target device to the next. Any idea how I might get started?Alt + Tab --> keystrokes get sent to the other phone
Thanks :)