read rssi of bluetooth low-energy beacon using bluez5
Asked Answered
Z

0

7

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)
Zoellick answered 4/6, 2014 at 12:34 Comment(3)
Hey! I'm really curious where did you find documentation for Bluez? I'm trying to use it my project and I can't find any documentation :( Just finding some examples on the internet, copy-pasting and trying to understand what's happening.Seibert
You can read these links: people.csail.mit.edu/albert/bluez-intro/c404.html and affix.sourceforge.net/affix-doc/x496.htmlPeruke
@vhax The Bluez intro is a bit outdated but still worth a read in terms of understanding the concepts. The HCI API has proven to be invaluable, but lacks the description of quite a lot of other important functions that aren't getting described anywhere else.Overriding

© 2022 - 2024 — McMap. All rights reserved.