C++ rfcomm bluetooth problems

238 views Asked by At

Im trying to create a bluetooth listener that accepts incoming bluetooth connect requests, im doing this on a linux computer (ubuntu 20.04),using vscode, here's the code:

{

struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; 
char buf[1024] = { 0 }; 
int s;
int client, bytes_read; 
socklen_t opt = sizeof(rem_addr); 
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); 
loc_addr.rc_family = AF_BLUETOOTH;
str2ba("12:34:56:78:90:12", &loc_addr.rc_bdaddr);
loc_addr.rc_channel = (uint8_t) 1;


if (s == -1) {
    perror("socket");
    return 1;
}

if (bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) == -1) {
    perror("bind");
    return 1;
}
if (listen(s, 3) == -1) {
    perror("listen");
    return 1;
}else {
    cout << "listening" << endl;
}

struct sockaddr_rc name = { 0 };
socklen_t len = sizeof(name);
if (getsockname(s, (struct sockaddr *)&name, &len) == -1) {
    perror("getsockname");
    return 1;
}

char addr[18] = { 0 };
ba2str(&name.rc_bdaddr, addr);
cout << "Local address: " << addr << endl;
cout << "Local port: " << (int)name.rc_channel << endl;

// sockaddr_rc name = { 0 };
getsockname(s, (struct sockaddr *)&name, &opt);
ba2str( &name.rc_bdaddr, buf );
cout<<"local mac adress: "<<buf<<"\n";

// put socket into listening mode 

int val;
socklen_t len2 = sizeof(val);
if (getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, &val, &len2) == -1) {
    perror("getsockopt");
    return 1;
}else if(val) {
    printf("getsockopt() succeeded: val=%d, len2=%d\n", val, len2);
}else if(getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, &val, &len2) == 0) {
    printf("socket %d is not listening\n", s);}
opt = sizeof(rem_addr);
 
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
if(client<0){
    cout<<"error accepting connection\n";
}
else{
    cout<<"accepted connection from "<<buf<<"\n";
}
memset(buf, 0, sizeof(buf));

// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
    printf("received [%s]\n", buf);
} 

// close connection 
close(client); 
close(s); 
return 0;
}

I've replaced my local mac adress with "12:34:56:78:90:12" for privacy reasons (I'm 100% sure that im using the correct adress). When im running the code, this is what it returns

Local address: 12:34:56:78:90:12
Local port: 1
local mac adress: 12:34:56:78:90:12
socket 3 is not listening

why is the socket not a listening socket although ive used the listen function? connecting a bluetooth device is not an issue, there's nothing wrong with the bluetooth dongle Im using

1

There are 1 answers

0
petzval On

I suspect those C connect/accept functions no longer work with bluez. Answer number one is to learn dbus and its Bluetooth interface. But there may be a very much simpler answer by using this (my) github library https://github.com/petzval/btferret . However, it is written for a Raspberry Pi and I only have one report of it working on Ubuntu so it may be a fool's errand. But for what it's worth, this code can be connected from, and will respond to, a Bluetooth serial terminal with line end set to line feed.

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

int callback(int clientnode,unsigned char *dat,int len);

int main()
  {    
  if(init_blue("devices.txt") == 0)
    return(0);
    
    // specify termination char = 10 (line feed)
  classic_server(ANY_DEVICE,callback,10,KEY_ON | PASSKEY_LOCAL);
  close_all();
  return(0);
  }

int callback(int clientnode,unsigned char *dat,int len)
  {
    // client has sent dat[] length len terminated by 10
  printf("Received from %s = %s",device_name(clientnode),dat);
    // send 3 byte reply with line feed termination
  write_node(clientnode,"OK\n",3);
  return(SERVER_CONTINUE);
  }