void check_version(int dev_id) { struct hci_version ver; char *lmpver; if ((typ.dd = hci_open_dev(dev_id)) < 0) die("Could not open device\n"); if (hci_read_local_version(typ.dd, &ver, 1000) < 0) die("Can't read version info hci0\n"); lmpver = lmp_vertostr(ver.lmp_ver); if (strcmp(lmpver, "4.0")) { printf("You need a Bluetooth 4.0 LE device\n"); bt_free(lmpver); exit(1); } else { bt_free(lmpver); } hci_close_dev(typ.dd); }
void extra_info(int dd, int dev_id, bdaddr_t* bdaddr) { uint16_t handle, offset; uint8_t features[8], max_page = 0; char name[249], *tmp; char addr[19] = { 0 }; uint8_t mode, afh_map[10]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; int i, cc = 0; if (hci_devinfo(dev_id, &di) < 0) { perror("Can't get device info"); exit(1); } printf("Requesting information ...\n"); cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) { perror("Can't get connection info"); exit(1); } bacpy(&cr->bdaddr, bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { if (hci_create_connection(dd, bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); return; } sleep(1); cc = 1; } else handle = htobs(cr->conn_info->handle); ba2str(bdaddr, addr); printf("\tBD Address: %s\n", addr); if (hci_read_remote_name(dd, bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { char *ver = lmp_vertostr(version.lmp_ver); printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", ver ? ver : "n/a", version.lmp_ver, version.lmp_subver, bt_compidtostr(version.manufacturer), version.manufacturer); if (ver) bt_free(ver); } memset(features, 0, sizeof(features)); hci_read_remote_features(dd, handle, features, 20000); if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000); printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", (max_page > 0) ? " page 0" : "", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); tmp = lmp_featurestostr(features, "\t\t", 63); printf("%s\n", tmp); bt_free(tmp); for (i = 1; i <= max_page; i++) { if (hci_read_remote_ext_features(dd, handle, i, NULL, features, 20000) < 0) continue; printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); } if (hci_read_clock_offset(dd, handle, &offset, 1000) < 0) { perror("Reading clock offset failed"); exit(1); } printf("\tClock offset: 0x%4.4x\n", btohs(offset)); if(hci_read_afh_map(dd, handle, &mode, afh_map, 1000) < 0) { perror("HCI read AFH map request failed"); } if(mode == 0x01) { // DGS: Replace with call to btbb_print_afh_map - need a piconet printf("\tAFH Map: 0x"); for(i=0; i<10; i++) printf("%02x", afh_map[i]); printf("\n"); } else { printf("AFH disabled.\n"); } free(cr); if (cc) { usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); } }