Index: usr.sbin/bluetooth/hccontrol/hccontrol.8 =================================================================== --- usr.sbin/bluetooth/hccontrol/hccontrol.8 (revision 361107) +++ usr.sbin/bluetooth/hccontrol/hccontrol.8 (working copy) @@ -157,6 +157,10 @@ .It Cm LE_Read_Supported_States .It Cm LE_Read_Buffer_Size .It Cm LE Scan +.It Cm LE_Read_White_List_Size +.It Cm LE_Clear_White_List +.It Cm LE_Add_Device_To_White_List +.It Cm LE_Remove_Device_From_White_List .El .Pp The currently supported node commands in Index: usr.sbin/bluetooth/hccontrol/le.c =================================================================== --- usr.sbin/bluetooth/hccontrol/le.c (revision 361107) +++ usr.sbin/bluetooth/hccontrol/le.c (working copy) @@ -63,6 +63,10 @@ static int le_read_advertising_channel_tx_power(int s, int argc, char *argv[]); static int le_scan(int s, int argc, char *argv[]); static void handle_le_event(ng_hci_event_pkt_t* e, bool verbose); +static int le_read_white_list_size(int s, int argc, char *argv[]); +static int le_clear_white_list(int s, int argc, char *argv[]); +static int le_add_device_to_white_list(int s, int argc, char *argv[]); +static int le_remove_device_from_white_list(int s, int argc, char *argv[]); static int le_set_scan_param(int s, int argc, char *argv[]) @@ -762,6 +766,173 @@ } } +static int +le_read_white_list_size(int s, int argc, char *argv[]) +{ + ng_hci_le_read_white_list_size_rp rp; + int n; + + n = sizeof(rp); + + if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_READ_WHITE_LIST_SIZE), + (void *)&rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + fprintf(stdout, "White list size: %d\n", + (uint8_t)rp.white_list_size); + + return (OK); +} + +static int +le_clear_white_list(int s, int argc, char *argv[]) +{ + ng_hci_le_clear_white_list_rp rp; + int n; + + n = sizeof(rp); + + if (hci_simple_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_CLEAR_WHITE_LIST), + (void *)&rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + fprintf(stdout, "White list cleared\n"); + + return (OK); +} + +static int +le_add_device_to_white_list(int s, int argc, char *argv[]) +{ + ng_hci_le_add_device_to_white_list_cp cp; + ng_hci_le_add_device_to_white_list_rp rp; + int n; + char ch; + optreset = 1; + optind = 0; + bool addr_set = false; + + n = sizeof(rp); + + cp.address_type = 0x00; + + while ((ch = getopt(argc, argv , "t:a:")) != -1) { + switch(ch) { + case 't': + if (strcmp(optarg, "public") == 0) + cp.address_type = 0x00; + else if (strcmp(optarg, "random") == 0) + cp.address_type = 0x01; + else + return (USAGE); + break; + case 'a': + addr_set = true; + if (!bt_aton(optarg, &cp.address)) { + struct hostent *he = NULL; + + if ((he = bt_gethostbyname(optarg)) == NULL) + return (USAGE); + + memcpy(&cp.address, he->h_addr, + sizeof(cp.address)); + } + break; + } + } + + if (addr_set == false) + return (USAGE); + + if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_ADD_DEVICE_TO_WHITE_LIST), + (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + fprintf(stdout, "Address added to white list\n"); + + return (OK); +} + +static int +le_remove_device_from_white_list(int s, int argc, char *argv[]) +{ + ng_hci_le_remove_device_from_white_list_cp cp; + ng_hci_le_remove_device_from_white_list_rp rp; + int n; + char ch; + optreset = 1; + optind = 0; + bool addr_set = false; + + n = sizeof(rp); + + cp.address_type = 0x00; + + while ((ch = getopt(argc, argv , "t:a:")) != -1) { + switch(ch) { + case 't': + if (strcmp(optarg, "public") == 0) + cp.address_type = 0x00; + else if (strcmp(optarg, "random") == 0) + cp.address_type = 0x01; + else + return (USAGE); + break; + case 'a': + addr_set = true; + if (!bt_aton(optarg, &cp.address)) { + struct hostent *he = NULL; + + if ((he = bt_gethostbyname(optarg)) == NULL) + return (USAGE); + + memcpy(&cp.address, he->h_addr, + sizeof(cp.address)); + } + break; + } + } + + if (addr_set == false) + return (USAGE); + + if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, + NG_HCI_OCF_LE_ADD_DEVICE_TO_WHITE_LIST), + (void *)&cp, sizeof(cp), (void *)&rp, &n) == ERROR) + return (ERROR); + + if (rp.status != 0x00) { + fprintf(stdout, "Status: %s [%#02x]\n", + hci_status2str(rp.status), rp.status); + return (FAILED); + } + + fprintf(stdout, "Address removed from white list\n"); + + return (OK); +} + struct hci_command le_commands[] = { { "le_enable", @@ -840,4 +1011,30 @@ "Do an LE scan", &le_scan }, + { + "le_read_white_list_size", + "le_read_white_list_size\n" + "Read total number of white list entries that can be stored", + &le_read_white_list_size + }, + { + "le_clear_white_list", + "le_clear_white_list\n" + "Clear the white list in the controller", + &le_clear_white_list + }, + { + "le_add_device_to_white_list", + "le_add_device_to_white_list\n" + "[-t public|random] -a address\n" + "Add device to the white list", + &le_add_device_to_white_list + }, + { + "le_remove_device_from_white_list", + "le_remove_device_from_white_list\n" + "[-t public|random] -a address\n" + "Remove device from the white list", + &le_remove_device_from_white_list + }, };