int connection_get_rssi(struct conn_info_handles *ci, int8_t *ret_rssi) { int8_t rssi; if (hci_read_rssi(ci->dd, htobs(ci->handle), &rssi, 1000) < 0) { return ERR_READ_RSSI_FAILED; } *ret_rssi = rssi; return 1; }
int read_rssi(int dev_id, uint16_t handle) { int8_t rssi; if (BDADDR) str2ba(BDADDR, &bdaddr); if ((typ.dd = hci_open_dev(dev_id)) < 0) die("Could not open device\n"); if (hci_read_rssi(typ.dd, handle, &rssi, 1000) < 0) die("Read RSSI failed\n"); hci_close_dev(typ.dd); return rssi; }
int get_rssi(bdaddr_t *bdaddr, struct hci_state current_hci_state) { struct hci_dev_info di; if (hci_devinfo(current_hci_state.device_id, &di) < 0) { perror("Can't get device info"); return(-1); } uint16_t handle; // int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to); // HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5 if (hci_create_connection(current_hci_state.device_handle, bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); // TODO close(dd); return(-1); } sleep(1); struct hci_conn_info_req *cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); bacpy(&cr->bdaddr, bdaddr); cr->type = ACL_LINK; if(ioctl(current_hci_state.device_handle, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); return(-1); } int8_t rssi; if(hci_read_rssi(current_hci_state.device_handle, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("Read RSSI failed"); return(-1); } printf("RSSI return value: %d\n", rssi); free(cr); usleep(10000); hci_disconnect(current_hci_state.device_handle, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); }
int main(int argc, const char* argv[]) { const char *hciDeviceIdOverride = NULL; int hciDeviceId = 0; int hciSocket; int serverL2capSock; struct sockaddr_l2 sockAddr; socklen_t sockAddrLen; int result; bdaddr_t clientBdAddr; int clientL2capSock; struct l2cap_conninfo l2capConnInfo; socklen_t l2capConnInfoLen; int hciHandle; fd_set afds; fd_set rfds; struct timeval tv; char stdinBuf[256 * 2 + 1]; char l2capSockBuf[256]; int len; int i; struct bt_security btSecurity; socklen_t btSecurityLen; uint8_t securityLevel = 0; // remove buffering setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); // setup signal handlers signal(SIGINT, signalHandler); signal(SIGKILL, signalHandler); signal(SIGHUP, signalHandler); signal(SIGUSR1, signalHandler); prctl(PR_SET_PDEATHSIG, SIGINT); // create socket serverL2capSock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (argc > 1 && strlen(argv[1]) > 0) { hciDeviceIdOverride = argv[1]; } if (hciDeviceIdOverride != NULL) { hciDeviceId = atoi(hciDeviceIdOverride); } else { // if no env variable given, use the first available device hciDeviceId = hci_get_route(NULL); } if (hciDeviceId < 0) { hciDeviceId = 0; // use device 0, if device id is invalid } printf("hciDeviceId %d\n", hciDeviceId); bdaddr_t daddr; hciSocket = hci_open_dev(hciDeviceId); if (hciSocket == -1) { printf("adapterState unsupported\n"); return -1; } if (hci_read_bd_addr(hciSocket, &daddr, 1000) == -1){ daddr = *BDADDR_ANY; } printf("bdaddr "); for(i = 5; i > 0; i--) { printf("%02x:", daddr.b[i]); } printf("%02x", daddr.b[0]); printf("\n"); // bind memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.l2_family = AF_BLUETOOTH; sockAddr.l2_bdaddr = daddr; sockAddr.l2_cid = htobs(ATT_CID); result = bind(serverL2capSock, (struct sockaddr*)&sockAddr, sizeof(sockAddr)); printf("bind %s\n", (result == -1) ? strerror(errno) : "success"); result = listen(serverL2capSock, 1); printf("listen %s\n", (result == -1) ? strerror(errno) : "success"); while (result != -1) { FD_ZERO(&afds); FD_SET(serverL2capSock, &afds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(serverL2capSock + 1, &afds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { break; } else if (SIGHUP == lastSignal || SIGUSR1 == lastSignal) { result = 0; } } else if (result && FD_ISSET(serverL2capSock, &afds)) { sockAddrLen = sizeof(sockAddr); clientL2capSock = accept(serverL2capSock, (struct sockaddr *)&sockAddr, &sockAddrLen); baswap(&clientBdAddr, &sockAddr.l2_bdaddr); printf("accept %s\n", batostr(&clientBdAddr)); l2capConnInfoLen = sizeof(l2capConnInfo); getsockopt(clientL2capSock, SOL_L2CAP, L2CAP_CONNINFO, &l2capConnInfo, &l2capConnInfoLen); hciHandle = l2capConnInfo.hci_handle; while(1) { FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(clientL2capSock, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; result = select(clientL2capSock + 1, &rfds, NULL, NULL, &tv); if (-1 == result) { if (SIGINT == lastSignal || SIGKILL == lastSignal) { break; } else if (SIGHUP == lastSignal) { result = 0; hci_disconnect(hciSocket, hciHandle, HCI_OE_USER_ENDED_CONNECTION, 1000); } else if (SIGUSR1 == lastSignal) { int8_t rssi = 0; for (i = 0; i < 100; i++) { hci_read_rssi(hciSocket, hciHandle, &rssi, 1000); if (rssi != 0) { break; } } if (rssi == 0) { rssi = 127; } printf("rssi = %d\n", rssi); } } else if (result) { if (FD_ISSET(0, &rfds)) { len = read(0, stdinBuf, sizeof(stdinBuf)); if (len <= 0) { break; } i = 0; while(stdinBuf[i] != '\n') { unsigned int data = 0; sscanf(&stdinBuf[i], "%02x", &data); l2capSockBuf[i / 2] = data; i += 2; } len = write(clientL2capSock, l2capSockBuf, (len - 1) / 2); } if (FD_ISSET(clientL2capSock, &rfds)) { len = read(clientL2capSock, l2capSockBuf, sizeof(l2capSockBuf)); if (len <= 0) { break; } btSecurityLen = sizeof(btSecurity); memset(&btSecurity, 0, btSecurityLen); getsockopt(clientL2capSock, SOL_BLUETOOTH, BT_SECURITY, &btSecurity, &btSecurityLen); if (securityLevel != btSecurity.level) { securityLevel = btSecurity.level; const char *securityLevelString; switch(securityLevel) { case BT_SECURITY_LOW: securityLevelString = "low"; break; case BT_SECURITY_MEDIUM: securityLevelString = "medium"; break; case BT_SECURITY_HIGH: securityLevelString = "high"; break; default: securityLevelString = "unknown"; break; } printf("security %s\n", securityLevelString); } printf("data "); for(i = 0; i < len; i++) { printf("%02x", ((int)l2capSockBuf[i]) & 0xff); } printf("\n"); } } } printf("disconnect %s\n", batostr(&clientBdAddr)); close(clientL2capSock); } } printf("close\n"); close(serverL2capSock); close(hciSocket); return 0; }
int main(int argc, char **argv) { printf("Program Start\n"); inquiry_info *ii = NULL; int max_rsp, num_rsp; int dev_id, sock, len, flags; int i; char addr[19] = { 0 }; char name[248] = { 0 }; bdaddr_t bdaddr; dev_id = hci_get_route(NULL); printf("Device ID : %d\n", dev_id); sock = hci_open_dev( dev_id ); printf("Socket ID : %d\n", sock); if (dev_id < 0 || sock < 0) { perror("opening socket"); exit(1); } len = 8; max_rsp = 255; flags = IREQ_CACHE_FLUSH; ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags); if( num_rsp < 0 ) perror("hci_inquiry"); for (i = 0; i < num_rsp; i++) { ba2str(&(ii+i)->bdaddr, addr); memset(name, 0, sizeof(name)); if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), name, 0) < 0) strcpy(name, "[unknown]"); printf("%s %s\n", addr, name); int8_t rssi; struct hci_conn_info_req *cr; cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if(!cr){ perror("Can't allocate memory"); exit(1); } str2ba(addr, &bdaddr); bacpy(&cr->bdaddr, &bdaddr); ba2str(&cr->bdaddr, addr); printf("debug: %s\n", addr); cr->type = ACL_LINK; int errorcode = ioctl(sock, HCIGETCONNINFO, (unsigned long) cr); if (errorcode < 0) { printf("Error code: %d\n", errorcode); printf("Error no is: %d\n", errno); printf("Error description is : %s\n", strerror(errno)); perror("Get connection info failed"); exit(1); } int return_rssi = hci_read_rssi(sock, htobs(cr->conn_info->handle), &rssi, 1000); printf("RSSI value: %d\n", rssi); printf("RSSI return: %d\n", return_rssi); free(cr); } free( ii ); close( sock ); return 0; }