title: read rssi of bluetooth low-energy beacon using bluez5
body: <p>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). </p>
  
  <p>My code works like a charm when only one adapter is connected, but after connecting the second adapter i'm receiving input/output errors. </p>
  
  <p>Does anybody know what's wrong with the code?</p>
  
  <p>Is there another way to read out the RSSI?</p>
  
  <pre><code>#include &lt;rssi.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  
  #include &lt;bluetooth/bluetooth.h&gt;
  #include &lt;bluetooth/hci.h&gt;
  #include &lt;bluetooth/hci_lib.h&gt;
  
  #include &lt;time.h&gt;
  #include &lt;unistd.h&gt;
  
  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-&gt;hci_deviceid = hci_deviceid;
      this-&gt;bt_addr = bt_addr;
      init();
  }
  Adapter::Adapter(const char* bt_addr) {
      this-&gt;bt_addr = bt_addr;
      if (hci_get_route(NULL) &gt;= 0)
          this-&gt;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(&amp;sockAddr, 0, sizeof(sockAddr));
      sockAddr.l2_family = AF_BLUETOOTH;
      bacpy(&amp;sockAddr.l2_bdaddr, BDADDR_ANY);
      sockAddr.l2_cid = htobs(ATT_CID);
  
      result = bind(l2capSock, (struct sockaddr*) &amp;sockAddr, sizeof(sockAddr));
      printf("BIND: %d\n", result);
      printf("bind %s\n", (result == -1) ? strerror(errno) : "success");
  
      // connect
      memset(&amp;sockAddr, 0, sizeof(sockAddr));
  
      sockAddr.l2_family = AF_BLUETOOTH;
      str2ba(bt_addr, &amp;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 *) &amp;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, &amp;l2capConnInfo,
              &amp;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, &amp;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() &lt; 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++;
      }
  }
  </code></pre>
  
  <p>header:</p>
  
  <pre><code>#ifndef RSS_H_
  #define RSS_H_
  
  #include &lt;bluetooth/bluetooth.h&gt;
  #include &lt;bluetooth/hci.h&gt;
  #include &lt;bluetooth/hci_lib.h&gt;
  #include &lt;stdint.h&gt;
  
  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_ */
  </code></pre>
  
  <p>log:</p>
  
  <pre><code>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)
  </code></pre>