xref: /freebsd/usr.sbin/bluetooth/hccontrol/le.c (revision bcff2d9100c3dedbbf2bfb84cdfcb547d81b8b83)
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