int main(int argc, char *argv[]) { int opt, sock, dev_id, lap = 0, uap = 0, delay = 5; int have_lap = 0; int have_uap = 0; int afh_enabled = 0; uint8_t mode, afh_map[10]; char *end, ubertooth_device = -1; char *bt_dev = "hci0"; char addr[19] = { 0 }; struct libusb_device_handle *devh = NULL; uint32_t clock; uint16_t accuracy, handle, offset; bdaddr_t bdaddr; btbb_piconet *pn; struct hci_dev_info di; int cc = 0; pn = btbb_piconet_new(); while ((opt=getopt(argc,argv,"hl:u:U:e:d:ab:w:")) != EOF) { switch(opt) { case 'l': lap = strtol(optarg, &end, 16); if (end != optarg) { ++have_lap; } break; case 'u': uap = strtol(optarg, &end, 16); if (end != optarg) { ++have_uap; } break; case 'U': ubertooth_device = atoi(optarg); break; case 'e': max_ac_errors = atoi(optarg); break; case 'd': dumpfile = fopen(optarg, "w"); if (dumpfile == NULL) { perror(optarg); return 1; } break; case 'a': afh_enabled = 1; break; case 'b': bt_dev = optarg; if (bt_dev == NULL) { perror(optarg); return 1; } break; case 'w': //wait delay = atoi(optarg); break; case 'h': default: usage(); return 1; } } dev_id = hci_devid(bt_dev); sock = hci_open_dev(dev_id); hci_read_clock(sock, 0, 0, &clock, &accuracy, 0); if ((have_lap != 1) || (have_uap != 1)) { printf("No address given, reading address from device\n"); hci_read_bd_addr(sock, &bdaddr, 0); lap = bdaddr.b[0] | bdaddr.b[1] << 8 | bdaddr.b[2] << 16; btbb_init_piconet(pn, lap); uap = bdaddr.b[3]; btbb_piconet_set_uap(pn, uap); printf("LAP=%06x UAP=%02x\n", lap, uap); } else if (have_lap && have_uap) { btbb_init_piconet(pn, lap); btbb_piconet_set_uap(pn, uap); printf("Address given, assuming address is remote\n"); sprintf(addr, "00:00:%02X:%02X:%02X:%02X", uap, (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF ); str2ba(addr, &bdaddr); printf("Address: %s\n", addr); if (hci_devinfo(dev_id, &di) < 0) { perror("Can't get device info"); return 1; } if (hci_create_connection(sock, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); return 1; } sleep(1); cc = 1; if (hci_read_clock_offset(sock, handle, &offset, 1000) < 0) { perror("Reading clock offset failed"); } clock += offset; //Experimental AFH map reading from remote device if(afh_enabled) { if(hci_read_afh_map(sock, handle, &mode, afh_map, 1000) < 0) { perror("HCI read AFH map request failed"); //exit(1); } if(mode == 0x01) { btbb_piconet_set_afh_map(pn, afh_map); btbb_print_afh_map(pn); } else { printf("AFH disabled.\n"); afh_enabled = 0; } } if (cc) { usleep(10000); hci_disconnect(sock, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); } } else {
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); } }