I want to read the RSSI simultaneously of an bluetooth lowenergy beacon, on 2 bluetooth le usb adapters. I'm using a fedora 20 system with bluez 5 and the LogiLink BT0015 adapters (CSR chip).
My code works like a charm when only one adapter is connected, but after connecting the second adapter i'm receiving input/output errors.
Does anybody know what's wrong with the code?
Is there another way to read out the RSSI?
#include <rssi.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <time.h>
#include <unistd.h>
class Adapter {
const char* bt_addr;
int hci_deviceid;
int hciSocket;
uint16_t hciHandle;
int l2capSock;
struct sockaddr_l2 sockAddr;
struct l2cap_conninfo l2capConnInfo;
socklen_t l2capConnInfoLen;
void init();
public:
Adapter(int hci_deviceid, const char* bt_addr);
Adapter(const char * bt_addr);
int getHciDeviceId();
int8_t read_rssi(int to);
};
Adapter::Adapter(int hci_deviceid, const char* bt_addr) {
this->hci_deviceid = hci_deviceid;
this->bt_addr = bt_addr;
init();
}
Adapter::Adapter(const char* bt_addr) {
this->bt_addr = bt_addr;
if (hci_get_route(NULL) >= 0)
this->hci_deviceid = hci_get_route(NULL);
init();
}
void Adapter::init(){
int result;
printf("INIT with: %s via hci%d\n", bt_addr, hci_deviceid);
hciSocket = hci_open_dev(hci_deviceid);
printf("HCISOCKET: %d\n", hciSocket);
printf("l2capSock %s\n", (l2capSock == -1) ? strerror(errno) : "success");
// create socket
l2capSock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
printf("L2CAPSOCK: %d\n", l2capSock);
printf("l2capSock %s\n", (l2capSock == -1) ? strerror(errno) : "success");
// bind
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.l2_family = AF_BLUETOOTH;
bacpy(&sockAddr.l2_bdaddr, BDADDR_ANY);
sockAddr.l2_cid = htobs(ATT_CID);
result = bind(l2capSock, (struct sockaddr*) &sockAddr, sizeof(sockAddr));
printf("BIND: %d\n", result);
printf("bind %s\n", (result == -1) ? strerror(errno) : "success");
// connect
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.l2_family = AF_BLUETOOTH;
str2ba(bt_addr, &sockAddr.l2_bdaddr);
sockAddr.l2_bdaddr_type = BDADDR_LE_RANDOM; // BDADDR_LE_PUBLIC/RANDOM
sockAddr.l2_cid = htobs(ATT_CID);
result = connect(l2capSock, (struct sockaddr *) &sockAddr,
sizeof(sockAddr));
printf("CONNECT L2CAPSOCK: %d\n", result);
printf("connect %i %s\n", result,
(result == -1) ? strerror(errno) : "success");
l2capConnInfoLen = sizeof(l2capConnInfo);
getsockopt(l2capSock, SOL_L2CAP, L2CAP_CONNINFO, &l2capConnInfo,
&l2capConnInfoLen);
hciHandle = l2capConnInfo.hci_handle;
printf("GETSOCKOPT L2CAPSOCK: %d\n", result);
printf("getsockopt %i %s\n", result,
(result == -1) ? strerror(errno) : "success");
}
int Adapter::getHciDeviceId(){
return hci_deviceid;
}
int8_t Adapter::read_rssi(int to) {
int8_t rssi = 200;
int result = hci_read_rssi(hciSocket, hciHandle, &rssi, to);
printf("hci_read_rssi: %i %s\n", result,
(result == -1) ? strerror(errno) : "success");
return rssi;
}
void sleep(int ms){
clock_t end_time = clock() + ms * CLOCKS_PER_SEC/1000;
while (clock() < end_time) {}
}
int main(int argc, const char* argv[]) {
Adapter myAdapter(0, argv[1]);
Adapter myAdapter2(1, argv[1]);
int counter = 0;
while (true) {
printf("%d: Adapter %d: RSSI: %i ", counter, myAdapter.getHciDeviceId(), myAdapter.read_rssi(100));
printf("%d: Adapter %d: RSSI: %i ", counter, myAdapter2.getHciDeviceId(), myAdapter2.read_rssi(100));
sleep(1000);
counter++;
}
}
header:
#ifndef RSS_H_
#define RSS_H_
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <stdint.h>
struct sockaddr_l2 {
sa_family_t l2_family;
unsigned short l2_psm;
bdaddr_t l2_bdaddr;
unsigned short l2_cid;
uint8_t l2_bdaddr_type;
};
#define L2CAP_CONNINFO 0x02
struct l2cap_conninfo {
uint16_t hci_handle;
uint8_t dev_class[3];
};
#define ATT_CID 4
#endif /* RSS_H_ */
log:
2 Adapters Connected, using hci1:
root@dduck-virtual-machine:~/git/Rssi/Rssi/build# ./rssi 90:03:B7:CA:27:92
INIT with: 90:03:B7:CA:27:92 via hci1
HCISOCKET: 3
l2capSock success
L2CAPSOCK: 4
l2capSock success
BIND: 0
bind success
CONNECT L2CAPSOCK: 0
connect 0 success
GETSOCKOPT L2CAPSOCK: 0
getsockopt 0 success
hci_read_rssi: 0 success
0: Adapter 1: RSSI: -57 hci_read_rssi: 0 success
1: Adapter 1: RSSI: -57 hci_read_rssi: 0 success
2: Adapter 1: RSSI: -57 hci_read_rssi: 0 success
3: Adapter 1: RSSI: -57 hci_read_rssi: 0 success
4: Adapter 1: RSSI: -57 hci_read_rssi: 0 success
2 Adapters connected, using hci0:
root@dduck-virtual-machine:~/git/Rssi/Rssi/build# ./rssi 90:03:B7:CA:27:92
INIT with: 90:03:B7:CA:27:92 via hci0
HCISOCKET: 3
l2capSock success
L2CAPSOCK: 4
l2capSock success
BIND: 0
bind success
CONNECT L2CAPSOCK: 0
connect 0 success
GETSOCKOPT L2CAPSOCK: 0
getsockopt 0 success
hci_read_rssi: -1 Input/output error
0: Adapter 0: RSSI: -56 hci_read_rssi: -1 Input/output error
1: Adapter 0: RSSI: -56 hci_read_rssi: -1 Input/output error
2: Adapter 0: RSSI: -56 hci_read_rssi: -1 Input/output error
2 adapters connected, using both (hci0, hci1):
root@dduck-virtual-machine:~/git/Rssi/Rssi/build# ./rssi 90:03:B7:CA:27:92
INIT with: 90:03:B7:CA:27:92 via hci0
HCISOCKET: 3
l2capSock success
L2CAPSOCK: 4
l2capSock success
BIND: 0
bind success
CONNECT L2CAPSOCK: 0
connect 0 success
GETSOCKOPT L2CAPSOCK: 0
getsockopt 0 success
INIT with: 90:03:B7:CA:27:92 via hci1
HCISOCKET: 5
l2capSock success
L2CAPSOCK: 6
l2capSock success
BIND: 0
bind success
CONNECT L2CAPSOCK: -1
connect -1 Device or resource busy
GETSOCKOPT L2CAPSOCK: -1
getsockopt -1 Transport endpoint is not connected
hci_read_rssi: -1 Input/output error
0: Adapter 0: RSSI: -56 hci_read_rssi: -1 Input/output error
0: Adapter 1: RSSI: -56 hci_read_rssi: -1 Input/output error
1: Adapter 0: RSSI: -56 hci_read_rssi: -1 Input/output error
1: Adapter 1: RSSI: -56 hci_read_rssi: -1 Input/output error
1adapter connected, using hci0:
root@dduck-virtual-machine:~/git/Rssi/Rssi/build# ./rssi 90:03:B7:CA:27:92
INIT with: 90:03:B7:CA:27:92 via hci0
HCISOCKET: 3
l2capSock success
L2CAPSOCK: 4
l2capSock success
BIND: 0
bind success
CONNECT L2CAPSOCK: 0
connect 0 success
GETSOCKOPT L2CAPSOCK: 0
getsockopt 0 success
hci_read_rssi: 0 success
0: Adapter 0: RSSI: 127 hci_read_rssi: 0 success
1: Adapter 0: RSSI: -55 hci_read_rssi: 0 success
2: Adapter 0: RSSI: -56 hci_read_rssi: 0 success
hciconfig:
hci1: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:03 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING PSCAN ISCAN
RX bytes:612 acl:0 sco:0 events:37 errors:0
TX bytes:943 acl:0 sco:0 commands:37 errors:0
Features: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT
Name: 'ubuntu-0'
Class: 0x6c0100
Service Classes: Rendering, Capturing, Audio, Telephony
Device Class: Computer, Uncategorized
HCI Version: 4.0 (0x6) Revision: 0x22bb
LMP Version: 4.0 (0x6) Subversion: 0x22bb
Manufacturer: Cambridge Silicon Radio (10)
hci0: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:04 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING PSCAN
RX bytes:687 acl:0 sco:0 events:45 errors:0
TX bytes:997 acl:0 sco:0 commands:43 errors:0
Features: 0xff 0xff 0x8f 0xfe 0xdb 0xff 0x5b 0x87
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy: RSWITCH HOLD SNIFF PARK
Link mode: SLAVE ACCEPT
Name: 'dduck-virtual-machine-0'
Class: 0x600100
Service Classes: Audio, Telephony
Device Class: Computer, Uncategorized
HCI Version: 4.0 (0x6) Revision: 0x22bb
LMP Version: 4.0 (0x6) Subversion: 0x22bb
Manufacturer: Cambridge Silicon Radio (10)