1*bcff2d91STakanori Watanabe /* 2*bcff2d91STakanori Watanabe * le.c 3*bcff2d91STakanori Watanabe * 4*bcff2d91STakanori Watanabe * Copyright (c) 2015 Takanori Watanabe <takawata@freebsd.org> 5*bcff2d91STakanori Watanabe * All rights reserved. 6*bcff2d91STakanori Watanabe * 7*bcff2d91STakanori Watanabe * Redistribution and use in source and binary forms, with or without 8*bcff2d91STakanori Watanabe * modification, are permitted provided that the following conditions 9*bcff2d91STakanori Watanabe * are met: 10*bcff2d91STakanori Watanabe * 1. Redistributions of source code must retain the above copyright 11*bcff2d91STakanori Watanabe * notice, this list of conditions and the following disclaimer. 12*bcff2d91STakanori Watanabe * 2. Redistributions in binary form must reproduce the above copyright 13*bcff2d91STakanori Watanabe * notice, this list of conditions and the following disclaimer in the 14*bcff2d91STakanori Watanabe * documentation and/or other materials provided with the distribution. 15*bcff2d91STakanori Watanabe * 16*bcff2d91STakanori Watanabe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*bcff2d91STakanori Watanabe * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*bcff2d91STakanori Watanabe * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*bcff2d91STakanori Watanabe * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*bcff2d91STakanori Watanabe * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*bcff2d91STakanori Watanabe * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*bcff2d91STakanori Watanabe * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*bcff2d91STakanori Watanabe * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*bcff2d91STakanori Watanabe * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*bcff2d91STakanori Watanabe * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*bcff2d91STakanori Watanabe * SUCH DAMAGE. 27*bcff2d91STakanori Watanabe * 28*bcff2d91STakanori Watanabe * $Id: hccontrol.c,v 1.5 2003/09/05 00:38:24 max Exp $ 29*bcff2d91STakanori Watanabe * $FreeBSD$ 30*bcff2d91STakanori Watanabe */ 31*bcff2d91STakanori Watanabe 32*bcff2d91STakanori Watanabe #include <sys/types.h> 33*bcff2d91STakanori Watanabe #include <sys/ioctl.h> 34*bcff2d91STakanori Watanabe #include <sys/sysctl.h> 35*bcff2d91STakanori Watanabe #include <sys/bitstring.h> 36*bcff2d91STakanori Watanabe #include <sys/select.h> 37*bcff2d91STakanori Watanabe #include <assert.h> 38*bcff2d91STakanori Watanabe #include <err.h> 39*bcff2d91STakanori Watanabe #include <errno.h> 40*bcff2d91STakanori Watanabe #include <netgraph/ng_message.h> 41*bcff2d91STakanori Watanabe #include <errno.h> 42*bcff2d91STakanori Watanabe #include <stdio.h> 43*bcff2d91STakanori Watanabe #include <stdlib.h> 44*bcff2d91STakanori Watanabe #include <string.h> 45*bcff2d91STakanori Watanabe #include <unistd.h> 46*bcff2d91STakanori Watanabe #define L2CAP_SOCKET_CHECKED 47*bcff2d91STakanori Watanabe #include <bluetooth.h> 48*bcff2d91STakanori Watanabe #include "hccontrol.h" 49*bcff2d91STakanori Watanabe static int le_set_scan_param(int s, int argc, char *argv[]); 50*bcff2d91STakanori Watanabe static int le_set_scan_enable(int s, int argc, char *argv[]); 51*bcff2d91STakanori Watanabe static int parse_param(int argc, char *argv[], char *buf, int *len); 52*bcff2d91STakanori Watanabe static int le_set_scan_response(int s, int argc, char *argv[]); 53*bcff2d91STakanori Watanabe static int le_read_supported_status(int s, int argc, char *argv[]); 54*bcff2d91STakanori Watanabe static int le_read_local_supported_features(int s, int argc ,char *argv[]); 55*bcff2d91STakanori Watanabe static int set_le_event_mask(int s, uint64_t mask); 56*bcff2d91STakanori Watanabe static int set_event_mask(int s, uint64_t mask); 57*bcff2d91STakanori Watanabe static int le_enable(int s, int argc, char *argv[]); 58*bcff2d91STakanori Watanabe 59*bcff2d91STakanori Watanabe static int le_set_scan_param(int s, int argc, char *argv[]) 60*bcff2d91STakanori Watanabe { 61*bcff2d91STakanori Watanabe int type; 62*bcff2d91STakanori Watanabe int interval; 63*bcff2d91STakanori Watanabe int window; 64*bcff2d91STakanori Watanabe int adrtype; 65*bcff2d91STakanori Watanabe int policy; 66*bcff2d91STakanori Watanabe 67*bcff2d91STakanori Watanabe ng_hci_le_set_scan_parameters_cp cp; 68*bcff2d91STakanori Watanabe ng_hci_le_set_scan_parameters_rp rp; 69*bcff2d91STakanori Watanabe int e,n; 70*bcff2d91STakanori Watanabe 71*bcff2d91STakanori Watanabe if(argc != 5){ 72*bcff2d91STakanori Watanabe return USAGE; 73*bcff2d91STakanori Watanabe } 74*bcff2d91STakanori Watanabe 75*bcff2d91STakanori Watanabe if(strcmp(argv[0], "active")==0){ 76*bcff2d91STakanori Watanabe type = 1; 77*bcff2d91STakanori Watanabe }else if (strcmp(argv[0], "passive") == 0){ 78*bcff2d91STakanori Watanabe type = 0; 79*bcff2d91STakanori Watanabe }else{ 80*bcff2d91STakanori Watanabe return USAGE; 81*bcff2d91STakanori Watanabe } 82*bcff2d91STakanori Watanabe 83*bcff2d91STakanori Watanabe interval = (int)(atof(argv[1])/0.625); 84*bcff2d91STakanori Watanabe interval = (interval < 4)? 4: interval; 85*bcff2d91STakanori Watanabe window = (int)(atof(argv[2])/0.625); 86*bcff2d91STakanori Watanabe window = (window < 4) ? 4 : interval; 87*bcff2d91STakanori Watanabe 88*bcff2d91STakanori Watanabe if(strcmp(argv[3], "public")==0){ 89*bcff2d91STakanori Watanabe adrtype = 0; 90*bcff2d91STakanori Watanabe }else if (strcmp(argv[0], "random") == 0){ 91*bcff2d91STakanori Watanabe adrtype = 1; 92*bcff2d91STakanori Watanabe }else{ 93*bcff2d91STakanori Watanabe return USAGE; 94*bcff2d91STakanori Watanabe } 95*bcff2d91STakanori Watanabe 96*bcff2d91STakanori Watanabe if(strcmp(argv[4], "all")==0){ 97*bcff2d91STakanori Watanabe policy = 0; 98*bcff2d91STakanori Watanabe }else if (strcmp(argv[4], "whitelist") == 0){ 99*bcff2d91STakanori Watanabe policy = 1; 100*bcff2d91STakanori Watanabe }else{ 101*bcff2d91STakanori Watanabe return USAGE; 102*bcff2d91STakanori Watanabe } 103*bcff2d91STakanori Watanabe 104*bcff2d91STakanori Watanabe 105*bcff2d91STakanori Watanabe cp.le_scan_type = type; 106*bcff2d91STakanori Watanabe cp.le_scan_interval = interval; 107*bcff2d91STakanori Watanabe cp.own_address_type = adrtype; 108*bcff2d91STakanori Watanabe cp.le_scan_window = window; 109*bcff2d91STakanori Watanabe cp.scanning_filter_policy = policy; 110*bcff2d91STakanori Watanabe n = sizeof(rp); 111*bcff2d91STakanori Watanabe e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, 112*bcff2d91STakanori Watanabe NG_HCI_OCF_LE_SET_SCAN_PARAMETERS), 113*bcff2d91STakanori Watanabe (void *)&cp, sizeof(cp), (void *)&rp, &n); 114*bcff2d91STakanori Watanabe 115*bcff2d91STakanori Watanabe 116*bcff2d91STakanori Watanabe return 0; 117*bcff2d91STakanori Watanabe 118*bcff2d91STakanori Watanabe } 119*bcff2d91STakanori Watanabe 120*bcff2d91STakanori Watanabe 121*bcff2d91STakanori Watanabe static int le_set_scan_enable(int s, int argc, char *argv[]) 122*bcff2d91STakanori Watanabe { 123*bcff2d91STakanori Watanabe ng_hci_le_set_scan_enable_cp cp; 124*bcff2d91STakanori Watanabe ng_hci_le_set_scan_enable_rp rp; 125*bcff2d91STakanori Watanabe int e,n,enable = 0; 126*bcff2d91STakanori Watanabe 127*bcff2d91STakanori Watanabe if(argc != 1) 128*bcff2d91STakanori Watanabe return USAGE; 129*bcff2d91STakanori Watanabe 130*bcff2d91STakanori Watanabe if(strcmp(argv[0], "enable") == 0){ 131*bcff2d91STakanori Watanabe enable = 1; 132*bcff2d91STakanori Watanabe }else if(strcmp(argv[0], "disable")!= 0){ 133*bcff2d91STakanori Watanabe return USAGE; 134*bcff2d91STakanori Watanabe } 135*bcff2d91STakanori Watanabe n = sizeof(rp); 136*bcff2d91STakanori Watanabe cp.le_scan_enable = enable; 137*bcff2d91STakanori Watanabe cp.filter_duplicates = 0; 138*bcff2d91STakanori Watanabe e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, 139*bcff2d91STakanori Watanabe NG_HCI_OCF_LE_SET_SCAN_ENABLE), 140*bcff2d91STakanori Watanabe (void *)&cp, sizeof(cp), (void *)&rp, &n); 141*bcff2d91STakanori Watanabe 142*bcff2d91STakanori Watanabe if(e != 0 || rp.status != 0){ 143*bcff2d91STakanori Watanabe return ERROR; 144*bcff2d91STakanori Watanabe } 145*bcff2d91STakanori Watanabe return OK; 146*bcff2d91STakanori Watanabe 147*bcff2d91STakanori Watanabe } 148*bcff2d91STakanori Watanabe static int parse_param(int argc, char *argv[], char *buf, int *len) 149*bcff2d91STakanori Watanabe { 150*bcff2d91STakanori Watanabe char *buflast = buf + (*len); 151*bcff2d91STakanori Watanabe char *curbuf = buf; 152*bcff2d91STakanori Watanabe char *token,*lenpos; 153*bcff2d91STakanori Watanabe int ch; 154*bcff2d91STakanori Watanabe int datalen; 155*bcff2d91STakanori Watanabe uint16_t value; 156*bcff2d91STakanori Watanabe optreset = 1; 157*bcff2d91STakanori Watanabe optind = 0; 158*bcff2d91STakanori Watanabe while((ch = getopt(argc, argv , "n:f:u:")) != -1){ 159*bcff2d91STakanori Watanabe switch(ch){ 160*bcff2d91STakanori Watanabe case 'n': 161*bcff2d91STakanori Watanabe datalen = strlen(optarg); 162*bcff2d91STakanori Watanabe if( (curbuf + datalen + 2)>= buflast){ 163*bcff2d91STakanori Watanabe goto done; 164*bcff2d91STakanori Watanabe } 165*bcff2d91STakanori Watanabe curbuf[0] = datalen + 1; 166*bcff2d91STakanori Watanabe curbuf[1] = 8; 167*bcff2d91STakanori Watanabe curbuf += 2; 168*bcff2d91STakanori Watanabe memcpy(curbuf, optarg, datalen); 169*bcff2d91STakanori Watanabe curbuf += datalen; 170*bcff2d91STakanori Watanabe break; 171*bcff2d91STakanori Watanabe case 'f': 172*bcff2d91STakanori Watanabe if(curbuf+3 >buflast){ 173*bcff2d91STakanori Watanabe goto done; 174*bcff2d91STakanori Watanabe } 175*bcff2d91STakanori Watanabe curbuf[0] = 2; 176*bcff2d91STakanori Watanabe curbuf[1] = 1; 177*bcff2d91STakanori Watanabe curbuf[2] = atoi(optarg); 178*bcff2d91STakanori Watanabe curbuf += 3; 179*bcff2d91STakanori Watanabe break; 180*bcff2d91STakanori Watanabe case 'u': 181*bcff2d91STakanori Watanabe lenpos = buf; 182*bcff2d91STakanori Watanabe if((buf+2)>= buflast) 183*bcff2d91STakanori Watanabe goto done; 184*bcff2d91STakanori Watanabe 185*bcff2d91STakanori Watanabe curbuf[1] = 2; 186*bcff2d91STakanori Watanabe *lenpos = 1; 187*bcff2d91STakanori Watanabe curbuf += 2; 188*bcff2d91STakanori Watanabe while((token = strsep(&optarg, ",")) != NULL){ 189*bcff2d91STakanori Watanabe value = strtol(token, NULL, 16); 190*bcff2d91STakanori Watanabe if((curbuf+2)>= buflast) 191*bcff2d91STakanori Watanabe break; 192*bcff2d91STakanori Watanabe curbuf[0] = value &0xff; 193*bcff2d91STakanori Watanabe curbuf[1] = (value>>8)&0xff; 194*bcff2d91STakanori Watanabe curbuf += 2; 195*bcff2d91STakanori Watanabe } 196*bcff2d91STakanori Watanabe 197*bcff2d91STakanori Watanabe } 198*bcff2d91STakanori Watanabe } 199*bcff2d91STakanori Watanabe done: 200*bcff2d91STakanori Watanabe *len = curbuf - buf; 201*bcff2d91STakanori Watanabe 202*bcff2d91STakanori Watanabe return OK; 203*bcff2d91STakanori Watanabe } 204*bcff2d91STakanori Watanabe 205*bcff2d91STakanori Watanabe static int le_set_scan_response(int s, int argc, char *argv[]) 206*bcff2d91STakanori Watanabe { 207*bcff2d91STakanori Watanabe ng_hci_le_set_scan_response_data_cp cp; 208*bcff2d91STakanori Watanabe ng_hci_le_set_scan_response_data_rp rp; 209*bcff2d91STakanori Watanabe int n; 210*bcff2d91STakanori Watanabe int e; 211*bcff2d91STakanori Watanabe int len; 212*bcff2d91STakanori Watanabe char buf[NG_HCI_ADVERTISING_DATA_SIZE]; 213*bcff2d91STakanori Watanabe len = sizeof(buf); 214*bcff2d91STakanori Watanabe parse_param(argc, argv, buf, &len); 215*bcff2d91STakanori Watanabe memset(cp.scan_response_data, 0, sizeof(cp.scan_response_data)); 216*bcff2d91STakanori Watanabe cp.scan_response_data_length = len; 217*bcff2d91STakanori Watanabe memcpy(cp.scan_response_data, buf, len); 218*bcff2d91STakanori Watanabe n = sizeof(rp); 219*bcff2d91STakanori Watanabe e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, 220*bcff2d91STakanori Watanabe NG_HCI_OCF_LE_SET_SCAN_RESPONSE_DATA), 221*bcff2d91STakanori Watanabe (void *)&cp, sizeof(cp), (void *)&rp, &n); 222*bcff2d91STakanori Watanabe 223*bcff2d91STakanori Watanabe printf("SEt SCAN RESPONSE %d %d %d\n", e, rp.status, n); 224*bcff2d91STakanori Watanabe 225*bcff2d91STakanori Watanabe return OK; 226*bcff2d91STakanori Watanabe } 227*bcff2d91STakanori Watanabe 228*bcff2d91STakanori Watanabe static int le_read_local_supported_features(int s, int argc ,char *argv[]) 229*bcff2d91STakanori Watanabe { 230*bcff2d91STakanori Watanabe ng_hci_le_read_local_supported_features_rp rp; 231*bcff2d91STakanori Watanabe int e; 232*bcff2d91STakanori Watanabe int n = sizeof(rp); 233*bcff2d91STakanori Watanabe e = hci_simple_request(s, 234*bcff2d91STakanori Watanabe NG_HCI_OPCODE(NG_HCI_OGF_LE, 235*bcff2d91STakanori Watanabe NG_HCI_OCF_LE_READ_LOCAL_SUPPORTED_FEATURES), 236*bcff2d91STakanori Watanabe (void *)&rp, &n); 237*bcff2d91STakanori Watanabe printf("LOCAL SUPPOREDED:%d %d %lu\n", e, rp.status, rp.le_features); 238*bcff2d91STakanori Watanabe 239*bcff2d91STakanori Watanabe return 0; 240*bcff2d91STakanori Watanabe 241*bcff2d91STakanori Watanabe } 242*bcff2d91STakanori Watanabe static int le_read_supported_status(int s, int argc, char *argv[]) 243*bcff2d91STakanori Watanabe { 244*bcff2d91STakanori Watanabe ng_hci_le_read_supported_status_rp rp; 245*bcff2d91STakanori Watanabe int e; 246*bcff2d91STakanori Watanabe int n = sizeof(rp); 247*bcff2d91STakanori Watanabe e = hci_simple_request(s, 248*bcff2d91STakanori Watanabe NG_HCI_OPCODE(NG_HCI_OGF_LE, 249*bcff2d91STakanori Watanabe NG_HCI_OCF_LE_READ_SUPPORTED_STATUS), 250*bcff2d91STakanori Watanabe (void *)&rp, &n); 251*bcff2d91STakanori Watanabe printf("LE_STATUS:%d %d %lx\n", e, rp.status, rp.le_status); 252*bcff2d91STakanori Watanabe 253*bcff2d91STakanori Watanabe return 0; 254*bcff2d91STakanori Watanabe 255*bcff2d91STakanori Watanabe } 256*bcff2d91STakanori Watanabe 257*bcff2d91STakanori Watanabe 258*bcff2d91STakanori Watanabe static int set_le_event_mask(int s, uint64_t mask) 259*bcff2d91STakanori Watanabe { 260*bcff2d91STakanori Watanabe ng_hci_le_set_event_mask_cp semc; 261*bcff2d91STakanori Watanabe ng_hci_le_set_event_mask_rp rp; 262*bcff2d91STakanori Watanabe int i, n ,e; 263*bcff2d91STakanori Watanabe 264*bcff2d91STakanori Watanabe n = sizeof(rp); 265*bcff2d91STakanori Watanabe 266*bcff2d91STakanori Watanabe for(i=0; i< NG_HCI_LE_EVENT_MASK_SIZE;i++){ 267*bcff2d91STakanori Watanabe semc.event_mask[i] = mask&0xff; 268*bcff2d91STakanori Watanabe mask>>= 8; 269*bcff2d91STakanori Watanabe } 270*bcff2d91STakanori Watanabe e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, NG_HCI_OCF_LE_SET_EVENT_MASK), (void *)&semc, sizeof(semc), (void *)&rp, &n); 271*bcff2d91STakanori Watanabe 272*bcff2d91STakanori Watanabe return 0; 273*bcff2d91STakanori Watanabe } 274*bcff2d91STakanori Watanabe 275*bcff2d91STakanori Watanabe 276*bcff2d91STakanori Watanabe static int set_event_mask(int s, uint64_t mask) 277*bcff2d91STakanori Watanabe { 278*bcff2d91STakanori Watanabe ng_hci_set_event_mask_cp semc; 279*bcff2d91STakanori Watanabe ng_hci_set_event_mask_rp rp; 280*bcff2d91STakanori Watanabe int i,n,e; 281*bcff2d91STakanori Watanabe 282*bcff2d91STakanori Watanabe n = sizeof(rp); 283*bcff2d91STakanori Watanabe 284*bcff2d91STakanori Watanabe for(i=0; i< NG_HCI_EVENT_MASK_SIZE;i++){ 285*bcff2d91STakanori Watanabe semc.event_mask[i] = mask&0xff; 286*bcff2d91STakanori Watanabe mask>>= 8; 287*bcff2d91STakanori Watanabe } 288*bcff2d91STakanori Watanabe e = hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_SET_EVENT_MASK), (void *)&semc, sizeof(semc), (void *)&rp, &n); 289*bcff2d91STakanori Watanabe 290*bcff2d91STakanori Watanabe return 0; 291*bcff2d91STakanori Watanabe } 292*bcff2d91STakanori Watanabe 293*bcff2d91STakanori Watanabe 294*bcff2d91STakanori Watanabe static int le_enable(int s, int argc, char *argv[]) 295*bcff2d91STakanori Watanabe { 296*bcff2d91STakanori Watanabe if(argc != 1){ 297*bcff2d91STakanori Watanabe return USAGE; 298*bcff2d91STakanori Watanabe } 299*bcff2d91STakanori Watanabe 300*bcff2d91STakanori Watanabe if(strcasecmp(argv[0], "enable")==0){ 301*bcff2d91STakanori Watanabe set_event_mask(s,NG_HCI_EVENT_MASK_DEFAULT | 302*bcff2d91STakanori Watanabe NG_HCI_EVENT_MASK_LE); 303*bcff2d91STakanori Watanabe set_le_event_mask(s, NG_HCI_LE_EVENT_MASK_ALL); 304*bcff2d91STakanori Watanabe }else if (strcasecmp(argv[0], "disble")==0){ 305*bcff2d91STakanori Watanabe set_event_mask(s,NG_HCI_EVENT_MASK_DEFAULT); 306*bcff2d91STakanori Watanabe }else{ 307*bcff2d91STakanori Watanabe return USAGE; 308*bcff2d91STakanori Watanabe } 309*bcff2d91STakanori Watanabe 310*bcff2d91STakanori Watanabe return OK; 311*bcff2d91STakanori Watanabe } 312*bcff2d91STakanori Watanabe 313*bcff2d91STakanori Watanabe struct hci_command le_commands[] = { 314*bcff2d91STakanori Watanabe { 315*bcff2d91STakanori Watanabe "le_enable", 316*bcff2d91STakanori Watanabe "le_enable [enable|disable] \n" 317*bcff2d91STakanori Watanabe "Enable LE event ", 318*bcff2d91STakanori Watanabe &le_enable, 319*bcff2d91STakanori Watanabe }, 320*bcff2d91STakanori Watanabe { 321*bcff2d91STakanori Watanabe "le_read_local_supported_features", 322*bcff2d91STakanori Watanabe "le_read_local_supported_features\n" 323*bcff2d91STakanori Watanabe "read local supported features mask", 324*bcff2d91STakanori Watanabe &le_read_local_supported_features, 325*bcff2d91STakanori Watanabe }, 326*bcff2d91STakanori Watanabe { 327*bcff2d91STakanori Watanabe "le_read_supported_status", 328*bcff2d91STakanori Watanabe "le_read_supported_status\n" 329*bcff2d91STakanori Watanabe "read supported status" 330*bcff2d91STakanori Watanabe , 331*bcff2d91STakanori Watanabe &le_read_supported_status, 332*bcff2d91STakanori Watanabe }, 333*bcff2d91STakanori Watanabe { 334*bcff2d91STakanori Watanabe "le_set_scan_response", 335*bcff2d91STakanori Watanabe "le_set_scan_response -n $name -f $flag -u $uuid16,$uuid16 \n" 336*bcff2d91STakanori Watanabe "set LE scan response data" 337*bcff2d91STakanori Watanabe , 338*bcff2d91STakanori Watanabe &le_set_scan_response, 339*bcff2d91STakanori Watanabe }, 340*bcff2d91STakanori Watanabe { 341*bcff2d91STakanori Watanabe "le_set_scan_enable", 342*bcff2d91STakanori Watanabe "le_set_scan_enable [enable|disable] \n" 343*bcff2d91STakanori Watanabe "enable or disable LE device scan", 344*bcff2d91STakanori Watanabe &le_set_scan_enable 345*bcff2d91STakanori Watanabe }, 346*bcff2d91STakanori Watanabe { 347*bcff2d91STakanori Watanabe "le_set_scan_param", 348*bcff2d91STakanori Watanabe "le_set_scan_param [active|passive] interval(ms) window(ms) [public|random] [all|whitelist] \n" 349*bcff2d91STakanori Watanabe "set LE device scan parameter", 350*bcff2d91STakanori Watanabe &le_set_scan_param 351*bcff2d91STakanori Watanabe }, 352*bcff2d91STakanori Watanabe }; 353