1*042d53a7SEvalZero /*
2*042d53a7SEvalZero * Licensed to the Apache Software Foundation (ASF) under one
3*042d53a7SEvalZero * or more contributor license agreements. See the NOTICE file
4*042d53a7SEvalZero * distributed with this work for additional information
5*042d53a7SEvalZero * regarding copyright ownership. The ASF licenses this file
6*042d53a7SEvalZero * to you under the Apache License, Version 2.0 (the
7*042d53a7SEvalZero * "License"); you may not use this file except in compliance
8*042d53a7SEvalZero * with the License. You may obtain a copy of the License at
9*042d53a7SEvalZero *
10*042d53a7SEvalZero * http://www.apache.org/licenses/LICENSE-2.0
11*042d53a7SEvalZero *
12*042d53a7SEvalZero * Unless required by applicable law or agreed to in writing,
13*042d53a7SEvalZero * software distributed under the License is distributed on an
14*042d53a7SEvalZero * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15*042d53a7SEvalZero * KIND, either express or implied. See the License for the
16*042d53a7SEvalZero * specific language governing permissions and limitations
17*042d53a7SEvalZero * under the License.
18*042d53a7SEvalZero */
19*042d53a7SEvalZero
20*042d53a7SEvalZero #include <assert.h>
21*042d53a7SEvalZero #include <inttypes.h>
22*042d53a7SEvalZero #include <errno.h>
23*042d53a7SEvalZero #include <string.h>
24*042d53a7SEvalZero
25*042d53a7SEvalZero #include "nimble/ble.h"
26*042d53a7SEvalZero #include "nimble/nimble_opt.h"
27*042d53a7SEvalZero #include "nimble/hci_common.h"
28*042d53a7SEvalZero #include "host/ble_gap.h"
29*042d53a7SEvalZero #include "host/ble_hs_adv.h"
30*042d53a7SEvalZero #include "host/ble_sm.h"
31*042d53a7SEvalZero #include "host/ble_eddystone.h"
32*042d53a7SEvalZero #include "host/ble_hs_id.h"
33*042d53a7SEvalZero #include "services/gatt/ble_svc_gatt.h"
34*042d53a7SEvalZero #include "../src/ble_hs_priv.h"
35*042d53a7SEvalZero
36*042d53a7SEvalZero #include "cmd.h"
37*042d53a7SEvalZero #include "btshell.h"
38*042d53a7SEvalZero #include "cmd_gatt.h"
39*042d53a7SEvalZero #include "cmd_l2cap.h"
40*042d53a7SEvalZero
41*042d53a7SEvalZero #include "nimble/npl_shell.h"
42*042d53a7SEvalZero
43*042d53a7SEvalZero #define BTSHELL_MODULE "btshell"
44*042d53a7SEvalZero
45*042d53a7SEvalZero int
cmd_parse_conn_start_end(uint16_t * out_conn,uint16_t * out_start,uint16_t * out_end)46*042d53a7SEvalZero cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start,
47*042d53a7SEvalZero uint16_t *out_end)
48*042d53a7SEvalZero {
49*042d53a7SEvalZero int rc;
50*042d53a7SEvalZero
51*042d53a7SEvalZero *out_conn = parse_arg_uint16("conn", &rc);
52*042d53a7SEvalZero if (rc != 0) {
53*042d53a7SEvalZero return rc;
54*042d53a7SEvalZero }
55*042d53a7SEvalZero
56*042d53a7SEvalZero *out_start = parse_arg_uint16("start", &rc);
57*042d53a7SEvalZero if (rc != 0) {
58*042d53a7SEvalZero return rc;
59*042d53a7SEvalZero }
60*042d53a7SEvalZero
61*042d53a7SEvalZero *out_end = parse_arg_uint16("end", &rc);
62*042d53a7SEvalZero if (rc != 0) {
63*042d53a7SEvalZero return rc;
64*042d53a7SEvalZero }
65*042d53a7SEvalZero
66*042d53a7SEvalZero return 0;
67*042d53a7SEvalZero }
68*042d53a7SEvalZero
69*042d53a7SEvalZero static const struct kv_pair cmd_own_addr_types[] = {
70*042d53a7SEvalZero { "public", BLE_OWN_ADDR_PUBLIC },
71*042d53a7SEvalZero { "random", BLE_OWN_ADDR_RANDOM },
72*042d53a7SEvalZero { "rpa_pub", BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT },
73*042d53a7SEvalZero { "rpa_rnd", BLE_OWN_ADDR_RPA_RANDOM_DEFAULT },
74*042d53a7SEvalZero { NULL }
75*042d53a7SEvalZero };
76*042d53a7SEvalZero
77*042d53a7SEvalZero static const struct kv_pair cmd_peer_addr_types[] = {
78*042d53a7SEvalZero { "public", BLE_ADDR_PUBLIC },
79*042d53a7SEvalZero { "random", BLE_ADDR_RANDOM },
80*042d53a7SEvalZero { "public_id", BLE_ADDR_PUBLIC_ID },
81*042d53a7SEvalZero { "random_id", BLE_ADDR_RANDOM_ID },
82*042d53a7SEvalZero { NULL }
83*042d53a7SEvalZero };
84*042d53a7SEvalZero
85*042d53a7SEvalZero static const struct kv_pair cmd_addr_type[] = {
86*042d53a7SEvalZero { "public", BLE_ADDR_PUBLIC },
87*042d53a7SEvalZero { "random", BLE_ADDR_RANDOM },
88*042d53a7SEvalZero { NULL }
89*042d53a7SEvalZero };
90*042d53a7SEvalZero
91*042d53a7SEvalZero
92*042d53a7SEvalZero
93*042d53a7SEvalZero /*****************************************************************************
94*042d53a7SEvalZero * $advertise *
95*042d53a7SEvalZero *****************************************************************************/
96*042d53a7SEvalZero static const struct kv_pair cmd_adv_filt_types[] = {
97*042d53a7SEvalZero { "none", BLE_HCI_ADV_FILT_NONE },
98*042d53a7SEvalZero { "scan", BLE_HCI_ADV_FILT_SCAN },
99*042d53a7SEvalZero { "conn", BLE_HCI_ADV_FILT_CONN },
100*042d53a7SEvalZero { "both", BLE_HCI_ADV_FILT_BOTH },
101*042d53a7SEvalZero { NULL }
102*042d53a7SEvalZero };
103*042d53a7SEvalZero
104*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
105*042d53a7SEvalZero static struct kv_pair cmd_ext_adv_phy_opts[] = {
106*042d53a7SEvalZero { "1M", 0x01 },
107*042d53a7SEvalZero { "2M", 0x02 },
108*042d53a7SEvalZero { "coded", 0x03 },
109*042d53a7SEvalZero { NULL }
110*042d53a7SEvalZero };
111*042d53a7SEvalZero
112*042d53a7SEvalZero static bool adv_instances[BLE_ADV_INSTANCES];
113*042d53a7SEvalZero
114*042d53a7SEvalZero static int
cmd_advertise_configure(int argc,char ** argv)115*042d53a7SEvalZero cmd_advertise_configure(int argc, char **argv)
116*042d53a7SEvalZero {
117*042d53a7SEvalZero struct ble_gap_ext_adv_params params = {0};
118*042d53a7SEvalZero int8_t selected_tx_power;
119*042d53a7SEvalZero uint8_t instance;
120*042d53a7SEvalZero int rc;
121*042d53a7SEvalZero
122*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
123*042d53a7SEvalZero if (rc != 0) {
124*042d53a7SEvalZero return rc;
125*042d53a7SEvalZero }
126*042d53a7SEvalZero
127*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
128*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
129*042d53a7SEvalZero console_printf("invalid instance\n");
130*042d53a7SEvalZero return rc;
131*042d53a7SEvalZero }
132*042d53a7SEvalZero
133*042d53a7SEvalZero if (adv_instances[instance]) {
134*042d53a7SEvalZero console_printf("instance already configured\n");
135*042d53a7SEvalZero return rc;
136*042d53a7SEvalZero }
137*042d53a7SEvalZero
138*042d53a7SEvalZero memset(¶ms, 0, sizeof(params));
139*042d53a7SEvalZero
140*042d53a7SEvalZero params.legacy_pdu = parse_arg_bool_dflt("legacy", 0, &rc);
141*042d53a7SEvalZero if (rc != 0) {
142*042d53a7SEvalZero console_printf("invalid 'legacy' parameter\n");
143*042d53a7SEvalZero return rc;
144*042d53a7SEvalZero }
145*042d53a7SEvalZero
146*042d53a7SEvalZero if (params.legacy_pdu) {
147*042d53a7SEvalZero params.connectable = 1;
148*042d53a7SEvalZero params.scannable = 1;
149*042d53a7SEvalZero }
150*042d53a7SEvalZero
151*042d53a7SEvalZero params.connectable = parse_arg_bool_dflt("connectable", params.connectable, &rc);
152*042d53a7SEvalZero if (rc != 0) {
153*042d53a7SEvalZero console_printf("invalid 'connectable' parameter\n");
154*042d53a7SEvalZero return rc;
155*042d53a7SEvalZero }
156*042d53a7SEvalZero
157*042d53a7SEvalZero params.scannable = parse_arg_bool_dflt("scannable", params.scannable, &rc);
158*042d53a7SEvalZero if (rc != 0) {
159*042d53a7SEvalZero console_printf("invalid 'scannable' parameter\n");
160*042d53a7SEvalZero return rc;
161*042d53a7SEvalZero }
162*042d53a7SEvalZero
163*042d53a7SEvalZero params.high_duty_directed = parse_arg_bool_dflt("high_duty", 0, &rc);
164*042d53a7SEvalZero if (rc != 0) {
165*042d53a7SEvalZero console_printf("invalid 'high_duty' parameter\n");
166*042d53a7SEvalZero return rc;
167*042d53a7SEvalZero }
168*042d53a7SEvalZero
169*042d53a7SEvalZero params.anonymous = parse_arg_bool_dflt("anonymous", 0, &rc);
170*042d53a7SEvalZero if (rc != 0) {
171*042d53a7SEvalZero console_printf("invalid 'anonymous' parameter\n");
172*042d53a7SEvalZero return rc;
173*042d53a7SEvalZero }
174*042d53a7SEvalZero
175*042d53a7SEvalZero params.include_tx_power = parse_arg_bool_dflt("include_tx_power", 0, &rc);
176*042d53a7SEvalZero if (rc != 0) {
177*042d53a7SEvalZero console_printf("invalid 'include_tx_power' parameter\n");
178*042d53a7SEvalZero return rc;
179*042d53a7SEvalZero }
180*042d53a7SEvalZero
181*042d53a7SEvalZero params.scan_req_notif = parse_arg_bool_dflt("scan_req_notif", 0, &rc);
182*042d53a7SEvalZero if (rc != 0) {
183*042d53a7SEvalZero console_printf("invalid 'scan_req_notif' parameter\n");
184*042d53a7SEvalZero return rc;
185*042d53a7SEvalZero }
186*042d53a7SEvalZero
187*042d53a7SEvalZero rc = parse_arg_mac("peer_addr", params.peer.val);
188*042d53a7SEvalZero if (rc == 0) {
189*042d53a7SEvalZero params.directed = 1;
190*042d53a7SEvalZero
191*042d53a7SEvalZero params.peer.type = parse_arg_kv_dflt("peer_addr_type",
192*042d53a7SEvalZero cmd_peer_addr_types,
193*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
194*042d53a7SEvalZero if (rc != 0) {
195*042d53a7SEvalZero console_printf("invalid 'peer_addr_type' parameter\n");
196*042d53a7SEvalZero return rc;
197*042d53a7SEvalZero }
198*042d53a7SEvalZero }
199*042d53a7SEvalZero else if (rc == ENOENT) {
200*042d53a7SEvalZero /* skip, no peer address provided */
201*042d53a7SEvalZero } else {
202*042d53a7SEvalZero console_printf("invalid 'peer_addr' parameter\n");
203*042d53a7SEvalZero return rc;
204*042d53a7SEvalZero }
205*042d53a7SEvalZero
206*042d53a7SEvalZero
207*042d53a7SEvalZero params.directed = parse_arg_bool_dflt("directed", params.directed, &rc);
208*042d53a7SEvalZero if (rc != 0) {
209*042d53a7SEvalZero console_printf("invalid 'directed' parameter\n");
210*042d53a7SEvalZero return rc;
211*042d53a7SEvalZero }
212*042d53a7SEvalZero
213*042d53a7SEvalZero if (params.directed && params.legacy_pdu) {
214*042d53a7SEvalZero params.scannable = 0;
215*042d53a7SEvalZero }
216*042d53a7SEvalZero
217*042d53a7SEvalZero params.own_addr_type = parse_arg_kv_dflt("own_addr_type",
218*042d53a7SEvalZero cmd_own_addr_types,
219*042d53a7SEvalZero BLE_OWN_ADDR_PUBLIC, &rc);
220*042d53a7SEvalZero if (rc != 0) {
221*042d53a7SEvalZero console_printf("invalid 'own_addr_type' parameter\n");
222*042d53a7SEvalZero return rc;
223*042d53a7SEvalZero }
224*042d53a7SEvalZero
225*042d53a7SEvalZero params.channel_map = parse_arg_uint8_dflt("channel_map", 0, &rc);
226*042d53a7SEvalZero if (rc != 0) {
227*042d53a7SEvalZero console_printf("invalid 'channel_map' parameter\n");
228*042d53a7SEvalZero return rc;
229*042d53a7SEvalZero }
230*042d53a7SEvalZero
231*042d53a7SEvalZero params.filter_policy = parse_arg_kv_dflt("filter", cmd_adv_filt_types,
232*042d53a7SEvalZero BLE_HCI_ADV_FILT_NONE, &rc);
233*042d53a7SEvalZero if (rc != 0) {
234*042d53a7SEvalZero console_printf("invalid 'filter' parameter\n");
235*042d53a7SEvalZero return rc;
236*042d53a7SEvalZero }
237*042d53a7SEvalZero
238*042d53a7SEvalZero params.itvl_min = parse_arg_uint32_dflt("interval_min", 0, &rc);
239*042d53a7SEvalZero if (rc != 0) {
240*042d53a7SEvalZero console_printf("invalid 'interval_min' parameter\n");
241*042d53a7SEvalZero return rc;
242*042d53a7SEvalZero }
243*042d53a7SEvalZero
244*042d53a7SEvalZero params.itvl_max = parse_arg_uint32_dflt("interval_max", 0, &rc);
245*042d53a7SEvalZero if (rc != 0) {
246*042d53a7SEvalZero console_printf("invalid 'interval_max' parameter\n");
247*042d53a7SEvalZero return rc;
248*042d53a7SEvalZero }
249*042d53a7SEvalZero
250*042d53a7SEvalZero params.tx_power = parse_arg_long_bounds_dflt("tx_power",
251*042d53a7SEvalZero -127, 127, 127, &rc);
252*042d53a7SEvalZero if (rc != 0) {
253*042d53a7SEvalZero console_printf("invalid 'tx_power' parameter\n");
254*042d53a7SEvalZero return rc;
255*042d53a7SEvalZero }
256*042d53a7SEvalZero
257*042d53a7SEvalZero params.primary_phy = parse_arg_kv_dflt("primary_phy", cmd_ext_adv_phy_opts,
258*042d53a7SEvalZero 1, &rc);
259*042d53a7SEvalZero if (rc != 0) {
260*042d53a7SEvalZero console_printf("invalid 'primary_phy' parameter\n");
261*042d53a7SEvalZero return rc;
262*042d53a7SEvalZero }
263*042d53a7SEvalZero
264*042d53a7SEvalZero params.secondary_phy = parse_arg_kv_dflt("secondary_phy",
265*042d53a7SEvalZero cmd_ext_adv_phy_opts,
266*042d53a7SEvalZero params.primary_phy, &rc);
267*042d53a7SEvalZero if (rc != 0) {
268*042d53a7SEvalZero console_printf("invalid 'secondary_phy' parameter\n");
269*042d53a7SEvalZero return rc;
270*042d53a7SEvalZero }
271*042d53a7SEvalZero
272*042d53a7SEvalZero params.sid = parse_arg_uint8_dflt("sid", 0, &rc);
273*042d53a7SEvalZero if (rc != 0) {
274*042d53a7SEvalZero console_printf("invalid 'sid' parameter\n");
275*042d53a7SEvalZero return rc;
276*042d53a7SEvalZero }
277*042d53a7SEvalZero
278*042d53a7SEvalZero rc = btshell_ext_adv_configure(instance, ¶ms, &selected_tx_power);
279*042d53a7SEvalZero if (rc) {
280*042d53a7SEvalZero console_printf("failed to configure advertising instance\n");
281*042d53a7SEvalZero return rc;
282*042d53a7SEvalZero }
283*042d53a7SEvalZero
284*042d53a7SEvalZero console_printf("Instance %u configured (selected tx power: %d)\n",
285*042d53a7SEvalZero instance, selected_tx_power);
286*042d53a7SEvalZero
287*042d53a7SEvalZero adv_instances[instance] = true;
288*042d53a7SEvalZero
289*042d53a7SEvalZero return 0;
290*042d53a7SEvalZero }
291*042d53a7SEvalZero
292*042d53a7SEvalZero static int
cmd_advertise_set_addr(int argc,char ** argv)293*042d53a7SEvalZero cmd_advertise_set_addr(int argc, char **argv)
294*042d53a7SEvalZero {
295*042d53a7SEvalZero ble_addr_t addr;
296*042d53a7SEvalZero uint8_t instance;
297*042d53a7SEvalZero int rc;
298*042d53a7SEvalZero
299*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
300*042d53a7SEvalZero if (rc != 0) {
301*042d53a7SEvalZero return rc;
302*042d53a7SEvalZero }
303*042d53a7SEvalZero
304*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
305*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
306*042d53a7SEvalZero console_printf("invalid instance\n");
307*042d53a7SEvalZero return rc;
308*042d53a7SEvalZero }
309*042d53a7SEvalZero
310*042d53a7SEvalZero if (!adv_instances[instance]) {
311*042d53a7SEvalZero console_printf("instance not configured\n");
312*042d53a7SEvalZero return rc;
313*042d53a7SEvalZero }
314*042d53a7SEvalZero
315*042d53a7SEvalZero rc = parse_arg_mac("addr", addr.val);
316*042d53a7SEvalZero if (rc != 0) {
317*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
318*042d53a7SEvalZero return rc;
319*042d53a7SEvalZero }
320*042d53a7SEvalZero
321*042d53a7SEvalZero addr.type = BLE_ADDR_RANDOM;
322*042d53a7SEvalZero
323*042d53a7SEvalZero rc = ble_gap_ext_adv_set_addr(instance, &addr);
324*042d53a7SEvalZero if (rc) {
325*042d53a7SEvalZero console_printf("failed to start advertising instance\n");
326*042d53a7SEvalZero return rc;
327*042d53a7SEvalZero }
328*042d53a7SEvalZero
329*042d53a7SEvalZero return 0;
330*042d53a7SEvalZero }
331*042d53a7SEvalZero
332*042d53a7SEvalZero static int
cmd_advertise_start(int argc,char ** argv)333*042d53a7SEvalZero cmd_advertise_start(int argc, char **argv)
334*042d53a7SEvalZero {
335*042d53a7SEvalZero int max_events;
336*042d53a7SEvalZero uint8_t instance;
337*042d53a7SEvalZero int duration;
338*042d53a7SEvalZero bool restart;
339*042d53a7SEvalZero int rc;
340*042d53a7SEvalZero
341*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
342*042d53a7SEvalZero if (rc != 0) {
343*042d53a7SEvalZero return rc;
344*042d53a7SEvalZero }
345*042d53a7SEvalZero
346*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
347*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
348*042d53a7SEvalZero console_printf("invalid instance\n");
349*042d53a7SEvalZero return rc;
350*042d53a7SEvalZero }
351*042d53a7SEvalZero
352*042d53a7SEvalZero if (!adv_instances[instance]) {
353*042d53a7SEvalZero console_printf("instance not configured\n");
354*042d53a7SEvalZero return rc;
355*042d53a7SEvalZero }
356*042d53a7SEvalZero
357*042d53a7SEvalZero duration = parse_arg_uint16_dflt("duration", 0, &rc);
358*042d53a7SEvalZero if (rc != 0) {
359*042d53a7SEvalZero console_printf("invalid 'duration' parameter\n");
360*042d53a7SEvalZero return rc;
361*042d53a7SEvalZero }
362*042d53a7SEvalZero
363*042d53a7SEvalZero max_events = parse_arg_uint8_dflt("max_events", 0, &rc);
364*042d53a7SEvalZero if (rc != 0) {
365*042d53a7SEvalZero console_printf("invalid 'max_events' parameter\n");
366*042d53a7SEvalZero return rc;
367*042d53a7SEvalZero }
368*042d53a7SEvalZero
369*042d53a7SEvalZero restart = parse_arg_bool_dflt("restart", 0, &rc);
370*042d53a7SEvalZero if (rc != 0) {
371*042d53a7SEvalZero console_printf("invalid 'restart' parameter\n");
372*042d53a7SEvalZero return rc;
373*042d53a7SEvalZero }
374*042d53a7SEvalZero
375*042d53a7SEvalZero rc = btshell_ext_adv_start(instance, duration, max_events, restart);
376*042d53a7SEvalZero if (rc) {
377*042d53a7SEvalZero console_printf("failed to start advertising instance\n");
378*042d53a7SEvalZero return rc;
379*042d53a7SEvalZero }
380*042d53a7SEvalZero
381*042d53a7SEvalZero return 0;
382*042d53a7SEvalZero }
383*042d53a7SEvalZero
384*042d53a7SEvalZero static int
cmd_advertise_stop(int argc,char ** argv)385*042d53a7SEvalZero cmd_advertise_stop(int argc, char **argv)
386*042d53a7SEvalZero {
387*042d53a7SEvalZero uint8_t instance;
388*042d53a7SEvalZero int rc;
389*042d53a7SEvalZero
390*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
391*042d53a7SEvalZero if (rc != 0) {
392*042d53a7SEvalZero return rc;
393*042d53a7SEvalZero }
394*042d53a7SEvalZero
395*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
396*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
397*042d53a7SEvalZero console_printf("invalid instance\n");
398*042d53a7SEvalZero return rc;
399*042d53a7SEvalZero }
400*042d53a7SEvalZero
401*042d53a7SEvalZero if (!adv_instances[instance]) {
402*042d53a7SEvalZero console_printf("instance not configured\n");
403*042d53a7SEvalZero return rc;
404*042d53a7SEvalZero }
405*042d53a7SEvalZero
406*042d53a7SEvalZero rc = btshell_ext_adv_stop(instance);
407*042d53a7SEvalZero if (rc) {
408*042d53a7SEvalZero console_printf("failed to stop advertising instance\n");
409*042d53a7SEvalZero return rc;
410*042d53a7SEvalZero }
411*042d53a7SEvalZero
412*042d53a7SEvalZero return 0;
413*042d53a7SEvalZero }
414*042d53a7SEvalZero
415*042d53a7SEvalZero static int
cmd_advertise_remove(int argc,char ** argv)416*042d53a7SEvalZero cmd_advertise_remove(int argc, char **argv)
417*042d53a7SEvalZero {
418*042d53a7SEvalZero uint8_t instance;
419*042d53a7SEvalZero int rc;
420*042d53a7SEvalZero
421*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
422*042d53a7SEvalZero if (rc != 0) {
423*042d53a7SEvalZero return rc;
424*042d53a7SEvalZero }
425*042d53a7SEvalZero
426*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
427*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
428*042d53a7SEvalZero console_printf("invalid instance\n");
429*042d53a7SEvalZero return rc;
430*042d53a7SEvalZero }
431*042d53a7SEvalZero
432*042d53a7SEvalZero if (!adv_instances[instance]) {
433*042d53a7SEvalZero console_printf("instance not configured\n");
434*042d53a7SEvalZero return rc;
435*042d53a7SEvalZero }
436*042d53a7SEvalZero
437*042d53a7SEvalZero rc = ble_gap_ext_adv_remove(instance);
438*042d53a7SEvalZero if (rc) {
439*042d53a7SEvalZero console_printf("failed to remove advertising instance\n");
440*042d53a7SEvalZero return rc;
441*042d53a7SEvalZero }
442*042d53a7SEvalZero
443*042d53a7SEvalZero adv_instances[instance] = false;
444*042d53a7SEvalZero
445*042d53a7SEvalZero return 0;
446*042d53a7SEvalZero }
447*042d53a7SEvalZero
448*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
449*042d53a7SEvalZero static const struct shell_param advertise_configure_params[] = {
450*042d53a7SEvalZero {"instance", "default: 0"},
451*042d53a7SEvalZero {"connectable", "connectable advertising, usage: =[0-1], default: 0"},
452*042d53a7SEvalZero {"scannable", "scannable advertising, usage: =[0-1], default: 0"},
453*042d53a7SEvalZero {"directed", "directed advertising, usage: =[0-1], default: 0"},
454*042d53a7SEvalZero {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
455*042d53a7SEvalZero {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
456*042d53a7SEvalZero {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
457*042d53a7SEvalZero {"channel_map", "usage: =[0x00-0xff], default: 0"},
458*042d53a7SEvalZero {"filter", "usage: =[none|scan|conn|both], default: none"},
459*042d53a7SEvalZero {"interval_min", "usage: =[0-UINT32_MAX], default: 0"},
460*042d53a7SEvalZero {"interval_max", "usage: =[0-UINT32_MAX], default: 0"},
461*042d53a7SEvalZero {"tx_power", "usage: =[-127-127], default: 127"},
462*042d53a7SEvalZero {"primary_phy", "usage: =[1M|coded], default: 1M"},
463*042d53a7SEvalZero {"secondary_phy", "usage: =[1M|2M|coded], default: primary_phy"},
464*042d53a7SEvalZero {"sid", "usage: =[0-UINT8_MAX], default: 0"},
465*042d53a7SEvalZero {"high_duty", "usage: =[0-1], default: 0"},
466*042d53a7SEvalZero {"anonymous", "enable anonymous advertising, usage: =[0-1], default: 0"},
467*042d53a7SEvalZero {"legacy", "use legacy PDUs, usage: =[0-1], default: 0"},
468*042d53a7SEvalZero {"include_tx_power", "include TX power in PDU, usage: =[0-1], default: 0"},
469*042d53a7SEvalZero {"scan_req_notif", "enable Scan Request notification usage: =[0-1], default: 0"},
470*042d53a7SEvalZero {NULL, NULL}
471*042d53a7SEvalZero };
472*042d53a7SEvalZero
473*042d53a7SEvalZero static const struct shell_cmd_help advertise_configure_help = {
474*042d53a7SEvalZero .summary = "configure new advertising instance",
475*042d53a7SEvalZero .usage = NULL,
476*042d53a7SEvalZero .params = advertise_configure_params,
477*042d53a7SEvalZero };
478*042d53a7SEvalZero
479*042d53a7SEvalZero static const struct shell_param advertise_set_addr_params[] = {
480*042d53a7SEvalZero {"instance", "default: 0"},
481*042d53a7SEvalZero {"addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
482*042d53a7SEvalZero {NULL, NULL}
483*042d53a7SEvalZero };
484*042d53a7SEvalZero
485*042d53a7SEvalZero static const struct shell_cmd_help advertise_set_addr_help = {
486*042d53a7SEvalZero .summary = "set advertising instance random address",
487*042d53a7SEvalZero .usage = NULL,
488*042d53a7SEvalZero .params = advertise_set_addr_params,
489*042d53a7SEvalZero };
490*042d53a7SEvalZero
491*042d53a7SEvalZero static const struct shell_param advertise_start_params[] = {
492*042d53a7SEvalZero {"instance", "default: 0"},
493*042d53a7SEvalZero {"duration", "advertising duration in 10ms units, default: 0 (forever)"},
494*042d53a7SEvalZero {"max_events", "max number of advertising events, default: 0 (no limit)"},
495*042d53a7SEvalZero {"restart", "restart advertising after disconnect, usage: =[0-1], default: 0"},
496*042d53a7SEvalZero {NULL, NULL}
497*042d53a7SEvalZero };
498*042d53a7SEvalZero
499*042d53a7SEvalZero static const struct shell_cmd_help advertise_start_help = {
500*042d53a7SEvalZero .summary = "start advertising instance",
501*042d53a7SEvalZero .usage = NULL,
502*042d53a7SEvalZero .params = advertise_start_params,
503*042d53a7SEvalZero };
504*042d53a7SEvalZero
505*042d53a7SEvalZero static const struct shell_param advertise_stop_params[] = {
506*042d53a7SEvalZero {"instance", "default: 0"},
507*042d53a7SEvalZero {NULL, NULL}
508*042d53a7SEvalZero };
509*042d53a7SEvalZero
510*042d53a7SEvalZero static const struct shell_cmd_help advertise_stop_help = {
511*042d53a7SEvalZero .summary = "stop advertising instance",
512*042d53a7SEvalZero .usage = NULL,
513*042d53a7SEvalZero .params = advertise_stop_params,
514*042d53a7SEvalZero };
515*042d53a7SEvalZero
516*042d53a7SEvalZero static const struct shell_param advertise_remove_params[] = {
517*042d53a7SEvalZero {"instance", "default: 0"},
518*042d53a7SEvalZero {NULL, NULL}
519*042d53a7SEvalZero };
520*042d53a7SEvalZero
521*042d53a7SEvalZero static const struct shell_cmd_help advertise_remove_help = {
522*042d53a7SEvalZero .summary = "remove advertising instance",
523*042d53a7SEvalZero .usage = NULL,
524*042d53a7SEvalZero .params = advertise_remove_params,
525*042d53a7SEvalZero };
526*042d53a7SEvalZero #endif
527*042d53a7SEvalZero
528*042d53a7SEvalZero #else
529*042d53a7SEvalZero static const struct kv_pair cmd_adv_conn_modes[] = {
530*042d53a7SEvalZero { "non", BLE_GAP_CONN_MODE_NON },
531*042d53a7SEvalZero { "und", BLE_GAP_CONN_MODE_UND },
532*042d53a7SEvalZero { "dir", BLE_GAP_CONN_MODE_DIR },
533*042d53a7SEvalZero { NULL }
534*042d53a7SEvalZero };
535*042d53a7SEvalZero
536*042d53a7SEvalZero static const struct kv_pair cmd_adv_disc_modes[] = {
537*042d53a7SEvalZero { "non", BLE_GAP_DISC_MODE_NON },
538*042d53a7SEvalZero { "ltd", BLE_GAP_DISC_MODE_LTD },
539*042d53a7SEvalZero { "gen", BLE_GAP_DISC_MODE_GEN },
540*042d53a7SEvalZero { NULL }
541*042d53a7SEvalZero };
542*042d53a7SEvalZero
543*042d53a7SEvalZero static int
cmd_advertise(int argc,char ** argv)544*042d53a7SEvalZero cmd_advertise(int argc, char **argv)
545*042d53a7SEvalZero {
546*042d53a7SEvalZero struct ble_gap_adv_params params;
547*042d53a7SEvalZero int32_t duration_ms;
548*042d53a7SEvalZero ble_addr_t peer_addr;
549*042d53a7SEvalZero ble_addr_t *peer_addr_param = &peer_addr;
550*042d53a7SEvalZero uint8_t own_addr_type;
551*042d53a7SEvalZero bool restart;
552*042d53a7SEvalZero int rc;
553*042d53a7SEvalZero
554*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
555*042d53a7SEvalZero if (rc != 0) {
556*042d53a7SEvalZero return rc;
557*042d53a7SEvalZero }
558*042d53a7SEvalZero
559*042d53a7SEvalZero if (argc > 1 && strcmp(argv[1], "stop") == 0) {
560*042d53a7SEvalZero rc = btshell_adv_stop();
561*042d53a7SEvalZero if (rc != 0) {
562*042d53a7SEvalZero console_printf("advertise stop fail: %d\n", rc);
563*042d53a7SEvalZero return rc;
564*042d53a7SEvalZero }
565*042d53a7SEvalZero
566*042d53a7SEvalZero return 0;
567*042d53a7SEvalZero }
568*042d53a7SEvalZero
569*042d53a7SEvalZero params.conn_mode = parse_arg_kv_dflt("conn", cmd_adv_conn_modes,
570*042d53a7SEvalZero BLE_GAP_CONN_MODE_UND, &rc);
571*042d53a7SEvalZero if (rc != 0) {
572*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
573*042d53a7SEvalZero return rc;
574*042d53a7SEvalZero }
575*042d53a7SEvalZero
576*042d53a7SEvalZero params.disc_mode = parse_arg_kv_dflt("discov", cmd_adv_disc_modes,
577*042d53a7SEvalZero BLE_GAP_DISC_MODE_GEN, &rc);
578*042d53a7SEvalZero if (rc != 0) {
579*042d53a7SEvalZero console_printf("invalid 'discov' parameter\n");
580*042d53a7SEvalZero return rc;
581*042d53a7SEvalZero }
582*042d53a7SEvalZero
583*042d53a7SEvalZero peer_addr.type = parse_arg_kv_dflt("peer_addr_type", cmd_peer_addr_types,
584*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
585*042d53a7SEvalZero if (rc != 0) {
586*042d53a7SEvalZero console_printf("invalid 'peer_addr_type' parameter\n");
587*042d53a7SEvalZero return rc;
588*042d53a7SEvalZero }
589*042d53a7SEvalZero
590*042d53a7SEvalZero rc = parse_arg_mac("peer_addr", peer_addr.val);
591*042d53a7SEvalZero if (rc == ENOENT) {
592*042d53a7SEvalZero peer_addr_param = NULL;
593*042d53a7SEvalZero } else if (rc != 0) {
594*042d53a7SEvalZero console_printf("invalid 'peer_addr' parameter\n");
595*042d53a7SEvalZero return rc;
596*042d53a7SEvalZero }
597*042d53a7SEvalZero
598*042d53a7SEvalZero restart = parse_arg_bool_dflt("restart", 0, &rc);
599*042d53a7SEvalZero if (rc != 0) {
600*042d53a7SEvalZero console_printf("invalid 'restart' parameter\n");
601*042d53a7SEvalZero return rc;
602*042d53a7SEvalZero }
603*042d53a7SEvalZero
604*042d53a7SEvalZero own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
605*042d53a7SEvalZero BLE_OWN_ADDR_PUBLIC, &rc);
606*042d53a7SEvalZero if (rc != 0) {
607*042d53a7SEvalZero console_printf("invalid 'own_addr_type' parameter\n");
608*042d53a7SEvalZero return rc;
609*042d53a7SEvalZero }
610*042d53a7SEvalZero
611*042d53a7SEvalZero params.channel_map = parse_arg_uint8_dflt("channel_map", 0, &rc);
612*042d53a7SEvalZero if (rc != 0) {
613*042d53a7SEvalZero console_printf("invalid 'channel_map' parameter\n");
614*042d53a7SEvalZero return rc;
615*042d53a7SEvalZero }
616*042d53a7SEvalZero
617*042d53a7SEvalZero params.filter_policy = parse_arg_kv_dflt("filter", cmd_adv_filt_types,
618*042d53a7SEvalZero BLE_HCI_ADV_FILT_NONE, &rc);
619*042d53a7SEvalZero if (rc != 0) {
620*042d53a7SEvalZero console_printf("invalid 'filter' parameter\n");
621*042d53a7SEvalZero return rc;
622*042d53a7SEvalZero }
623*042d53a7SEvalZero
624*042d53a7SEvalZero params.itvl_min = parse_arg_uint16_dflt("interval_min", 0, &rc);
625*042d53a7SEvalZero if (rc != 0) {
626*042d53a7SEvalZero console_printf("invalid 'interval_min' parameter\n");
627*042d53a7SEvalZero return rc;
628*042d53a7SEvalZero }
629*042d53a7SEvalZero
630*042d53a7SEvalZero params.itvl_max = parse_arg_uint16_dflt("interval_max", 0, &rc);
631*042d53a7SEvalZero if (rc != 0) {
632*042d53a7SEvalZero console_printf("invalid 'interval_max' parameter\n");
633*042d53a7SEvalZero return rc;
634*042d53a7SEvalZero }
635*042d53a7SEvalZero
636*042d53a7SEvalZero params.high_duty_cycle = parse_arg_bool_dflt("high_duty", 0, &rc);
637*042d53a7SEvalZero if (rc != 0) {
638*042d53a7SEvalZero console_printf("invalid 'high_duty' parameter\n");
639*042d53a7SEvalZero return rc;
640*042d53a7SEvalZero }
641*042d53a7SEvalZero
642*042d53a7SEvalZero duration_ms = parse_arg_long_bounds_dflt("duration", 1, INT32_MAX,
643*042d53a7SEvalZero BLE_HS_FOREVER, &rc);
644*042d53a7SEvalZero if (rc != 0) {
645*042d53a7SEvalZero console_printf("invalid 'duration' parameter\n");
646*042d53a7SEvalZero return rc;
647*042d53a7SEvalZero }
648*042d53a7SEvalZero
649*042d53a7SEvalZero rc = btshell_adv_start(own_addr_type, peer_addr_param, duration_ms,
650*042d53a7SEvalZero ¶ms, restart);
651*042d53a7SEvalZero if (rc != 0) {
652*042d53a7SEvalZero console_printf("advertise fail: %d\n", rc);
653*042d53a7SEvalZero return rc;
654*042d53a7SEvalZero }
655*042d53a7SEvalZero
656*042d53a7SEvalZero return 0;
657*042d53a7SEvalZero }
658*042d53a7SEvalZero
659*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
660*042d53a7SEvalZero static const struct shell_param advertise_params[] = {
661*042d53a7SEvalZero {"stop", "stop advertising procedure"},
662*042d53a7SEvalZero {"conn", "connectable mode, usage: =[non|und|dir], default: und"},
663*042d53a7SEvalZero {"discov", "discoverable mode, usage: =[non|ltd|gen], default: gen"},
664*042d53a7SEvalZero {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
665*042d53a7SEvalZero {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
666*042d53a7SEvalZero {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
667*042d53a7SEvalZero {"channel_map", "usage: =[0x00-0xff], default: 0"},
668*042d53a7SEvalZero {"filter", "usage: =[none|scan|conn|both], default: none"},
669*042d53a7SEvalZero {"interval_min", "usage: =[0-UINT16_MAX], default: 0"},
670*042d53a7SEvalZero {"interval_max", "usage: =[0-UINT16_MAX], default: 0"},
671*042d53a7SEvalZero {"high_duty", "usage: =[0-1], default: 0"},
672*042d53a7SEvalZero {"duration", "usage: =[1-INT32_MAX], default: INT32_MAX"},
673*042d53a7SEvalZero {"restart", "restart advertising after disconnect, usage: =[0-1], default: 0"},
674*042d53a7SEvalZero {NULL, NULL}
675*042d53a7SEvalZero };
676*042d53a7SEvalZero
677*042d53a7SEvalZero static const struct shell_cmd_help advertise_help = {
678*042d53a7SEvalZero .summary = "start/stop advertising with specific parameters",
679*042d53a7SEvalZero .usage = NULL,
680*042d53a7SEvalZero .params = advertise_params,
681*042d53a7SEvalZero };
682*042d53a7SEvalZero #endif
683*042d53a7SEvalZero #endif
684*042d53a7SEvalZero
685*042d53a7SEvalZero /*****************************************************************************
686*042d53a7SEvalZero * $connect *
687*042d53a7SEvalZero *****************************************************************************/
688*042d53a7SEvalZero
689*042d53a7SEvalZero static struct kv_pair cmd_ext_conn_phy_opts[] = {
690*042d53a7SEvalZero { "none", 0x00 },
691*042d53a7SEvalZero { "1M", 0x01 },
692*042d53a7SEvalZero { "coded", 0x02 },
693*042d53a7SEvalZero { "both", 0x03 },
694*042d53a7SEvalZero { "all", 0x04 },
695*042d53a7SEvalZero { NULL }
696*042d53a7SEvalZero };
697*042d53a7SEvalZero
698*042d53a7SEvalZero static int
cmd_connect(int argc,char ** argv)699*042d53a7SEvalZero cmd_connect(int argc, char **argv)
700*042d53a7SEvalZero {
701*042d53a7SEvalZero struct ble_gap_conn_params phy_1M_params = {0};
702*042d53a7SEvalZero struct ble_gap_conn_params phy_coded_params = {0};
703*042d53a7SEvalZero struct ble_gap_conn_params phy_2M_params = {0};
704*042d53a7SEvalZero uint8_t ext;
705*042d53a7SEvalZero int32_t duration_ms;
706*042d53a7SEvalZero ble_addr_t peer_addr;
707*042d53a7SEvalZero ble_addr_t *peer_addr_param = &peer_addr;
708*042d53a7SEvalZero int own_addr_type;
709*042d53a7SEvalZero int rc;
710*042d53a7SEvalZero
711*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
712*042d53a7SEvalZero if (rc != 0) {
713*042d53a7SEvalZero return rc;
714*042d53a7SEvalZero }
715*042d53a7SEvalZero
716*042d53a7SEvalZero if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
717*042d53a7SEvalZero rc = btshell_conn_cancel();
718*042d53a7SEvalZero if (rc != 0) {
719*042d53a7SEvalZero console_printf("connection cancel fail: %d\n", rc);
720*042d53a7SEvalZero return rc;
721*042d53a7SEvalZero }
722*042d53a7SEvalZero
723*042d53a7SEvalZero return 0;
724*042d53a7SEvalZero }
725*042d53a7SEvalZero
726*042d53a7SEvalZero ext = parse_arg_kv_dflt("extended", cmd_ext_conn_phy_opts, 0, &rc);
727*042d53a7SEvalZero if (rc != 0) {
728*042d53a7SEvalZero console_printf("invalid 'extended' parameter\n");
729*042d53a7SEvalZero return rc;
730*042d53a7SEvalZero }
731*042d53a7SEvalZero
732*042d53a7SEvalZero peer_addr.type = parse_arg_kv_dflt("peer_addr_type", cmd_peer_addr_types,
733*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
734*042d53a7SEvalZero if (rc != 0) {
735*042d53a7SEvalZero console_printf("invalid 'peer_addr_type' parameter\n");
736*042d53a7SEvalZero return rc;
737*042d53a7SEvalZero }
738*042d53a7SEvalZero
739*042d53a7SEvalZero rc = parse_arg_mac("peer_addr", peer_addr.val);
740*042d53a7SEvalZero if (rc == ENOENT) {
741*042d53a7SEvalZero /* Allow "addr" for backwards compatibility. */
742*042d53a7SEvalZero rc = parse_arg_mac("addr", peer_addr.val);
743*042d53a7SEvalZero }
744*042d53a7SEvalZero
745*042d53a7SEvalZero if (rc == ENOENT) {
746*042d53a7SEvalZero /* With no "peer_addr" specified we'll use white list */
747*042d53a7SEvalZero peer_addr_param = NULL;
748*042d53a7SEvalZero } else if (rc != 0) {
749*042d53a7SEvalZero console_printf("invalid 'peer_addr' parameter\n");
750*042d53a7SEvalZero return rc;
751*042d53a7SEvalZero }
752*042d53a7SEvalZero
753*042d53a7SEvalZero own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
754*042d53a7SEvalZero BLE_OWN_ADDR_PUBLIC, &rc);
755*042d53a7SEvalZero if (rc != 0) {
756*042d53a7SEvalZero console_printf("invalid 'own_addr_type' parameter\n");
757*042d53a7SEvalZero return rc;
758*042d53a7SEvalZero }
759*042d53a7SEvalZero
760*042d53a7SEvalZero duration_ms = parse_arg_long_bounds_dflt("duration", 1, INT32_MAX, 0, &rc);
761*042d53a7SEvalZero if (rc != 0) {
762*042d53a7SEvalZero console_printf("invalid 'duration' parameter\n");
763*042d53a7SEvalZero return rc;
764*042d53a7SEvalZero }
765*042d53a7SEvalZero
766*042d53a7SEvalZero phy_1M_params.scan_itvl = parse_arg_uint16_dflt("scan_interval", 0x0010, &rc);
767*042d53a7SEvalZero if (rc != 0) {
768*042d53a7SEvalZero console_printf("invalid 'scan_interval' parameter\n");
769*042d53a7SEvalZero return rc;
770*042d53a7SEvalZero }
771*042d53a7SEvalZero
772*042d53a7SEvalZero phy_1M_params.scan_window = parse_arg_uint16_dflt("scan_window", 0x0010, &rc);
773*042d53a7SEvalZero if (rc != 0) {
774*042d53a7SEvalZero console_printf("invalid 'scan_window' parameter\n");
775*042d53a7SEvalZero return rc;
776*042d53a7SEvalZero }
777*042d53a7SEvalZero
778*042d53a7SEvalZero phy_1M_params.itvl_min = parse_arg_uint16_dflt("interval_min",
779*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MIN,
780*042d53a7SEvalZero &rc);
781*042d53a7SEvalZero if (rc != 0) {
782*042d53a7SEvalZero console_printf("invalid 'interval_min' parameter\n");
783*042d53a7SEvalZero return rc;
784*042d53a7SEvalZero }
785*042d53a7SEvalZero
786*042d53a7SEvalZero phy_1M_params.itvl_max = parse_arg_uint16_dflt("interval_max",
787*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MAX,
788*042d53a7SEvalZero &rc);
789*042d53a7SEvalZero if (rc != 0) {
790*042d53a7SEvalZero console_printf("invalid 'interval_max' parameter\n");
791*042d53a7SEvalZero return rc;
792*042d53a7SEvalZero }
793*042d53a7SEvalZero
794*042d53a7SEvalZero phy_1M_params.latency = parse_arg_uint16_dflt("latency", 0, &rc);
795*042d53a7SEvalZero if (rc != 0) {
796*042d53a7SEvalZero console_printf("invalid 'latency' parameter\n");
797*042d53a7SEvalZero return rc;
798*042d53a7SEvalZero }
799*042d53a7SEvalZero
800*042d53a7SEvalZero phy_1M_params.supervision_timeout = parse_arg_uint16_dflt("timeout", 0x0100, &rc);
801*042d53a7SEvalZero if (rc != 0) {
802*042d53a7SEvalZero console_printf("invalid 'timeout' parameter\n");
803*042d53a7SEvalZero return rc;
804*042d53a7SEvalZero }
805*042d53a7SEvalZero
806*042d53a7SEvalZero phy_1M_params.min_ce_len = parse_arg_uint16_dflt("min_conn_event_len",
807*042d53a7SEvalZero 0x0010, &rc);
808*042d53a7SEvalZero if (rc != 0) {
809*042d53a7SEvalZero console_printf("invalid 'min_conn_event_len' parameter\n");
810*042d53a7SEvalZero return rc;
811*042d53a7SEvalZero }
812*042d53a7SEvalZero
813*042d53a7SEvalZero phy_1M_params.max_ce_len = parse_arg_uint16_dflt("max_conn_event_len",
814*042d53a7SEvalZero 0x0300, &rc);
815*042d53a7SEvalZero if (rc != 0) {
816*042d53a7SEvalZero console_printf("invalid 'max_conn_event_len' parameter\n");
817*042d53a7SEvalZero return rc;
818*042d53a7SEvalZero }
819*042d53a7SEvalZero
820*042d53a7SEvalZero if (ext == 0x00) {
821*042d53a7SEvalZero rc = btshell_conn_initiate(own_addr_type, peer_addr_param, duration_ms,
822*042d53a7SEvalZero &phy_1M_params);
823*042d53a7SEvalZero console_printf("error connecting; rc=%d\n", rc);
824*042d53a7SEvalZero return rc;
825*042d53a7SEvalZero }
826*042d53a7SEvalZero
827*042d53a7SEvalZero if (ext == 0x01) {
828*042d53a7SEvalZero rc = btshell_ext_conn_initiate(own_addr_type, peer_addr_param,
829*042d53a7SEvalZero duration_ms, &phy_1M_params,
830*042d53a7SEvalZero NULL, NULL);
831*042d53a7SEvalZero console_printf("error connecting; rc=%d\n", rc);
832*042d53a7SEvalZero return rc;
833*042d53a7SEvalZero }
834*042d53a7SEvalZero
835*042d53a7SEvalZero /* Get coded params */
836*042d53a7SEvalZero phy_coded_params.scan_itvl = parse_arg_uint16_dflt("coded_scan_interval",
837*042d53a7SEvalZero 0x0010, &rc);
838*042d53a7SEvalZero if (rc != 0) {
839*042d53a7SEvalZero console_printf("invalid 'coded_scan_interval' parameter\n");
840*042d53a7SEvalZero return rc;
841*042d53a7SEvalZero }
842*042d53a7SEvalZero
843*042d53a7SEvalZero phy_coded_params.scan_window = parse_arg_uint16_dflt("coded_scan_window",
844*042d53a7SEvalZero 0x0010, &rc);
845*042d53a7SEvalZero if (rc != 0) {
846*042d53a7SEvalZero console_printf("invalid 'coded_scan_window' parameter\n");
847*042d53a7SEvalZero return rc;
848*042d53a7SEvalZero }
849*042d53a7SEvalZero
850*042d53a7SEvalZero phy_coded_params.itvl_min = parse_arg_uint16_dflt("coded_interval_min",
851*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MIN,
852*042d53a7SEvalZero &rc);
853*042d53a7SEvalZero if (rc != 0) {
854*042d53a7SEvalZero console_printf("invalid 'coded_interval_min' parameter\n");
855*042d53a7SEvalZero return rc;
856*042d53a7SEvalZero }
857*042d53a7SEvalZero
858*042d53a7SEvalZero phy_coded_params.itvl_max = parse_arg_uint16_dflt("coded_interval_max",
859*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MAX,
860*042d53a7SEvalZero &rc);
861*042d53a7SEvalZero if (rc != 0) {
862*042d53a7SEvalZero console_printf("invalid 'coded_interval_max' parameter\n");
863*042d53a7SEvalZero return rc;
864*042d53a7SEvalZero }
865*042d53a7SEvalZero
866*042d53a7SEvalZero phy_coded_params.latency =
867*042d53a7SEvalZero parse_arg_uint16_dflt("coded_latency", 0, &rc);
868*042d53a7SEvalZero if (rc != 0) {
869*042d53a7SEvalZero console_printf("invalid 'coded_latency' parameter\n");
870*042d53a7SEvalZero return rc;
871*042d53a7SEvalZero }
872*042d53a7SEvalZero
873*042d53a7SEvalZero phy_coded_params.supervision_timeout =
874*042d53a7SEvalZero parse_arg_uint16_dflt("coded_timeout", 0x0100, &rc);
875*042d53a7SEvalZero
876*042d53a7SEvalZero if (rc != 0) {
877*042d53a7SEvalZero console_printf("invalid 'coded_timeout' parameter\n");
878*042d53a7SEvalZero return rc;
879*042d53a7SEvalZero }
880*042d53a7SEvalZero
881*042d53a7SEvalZero phy_coded_params.min_ce_len =
882*042d53a7SEvalZero parse_arg_uint16_dflt("coded_min_conn_event", 0x0010, &rc);
883*042d53a7SEvalZero if (rc != 0) {
884*042d53a7SEvalZero console_printf("invalid 'coded_min_conn_event' parameter\n");
885*042d53a7SEvalZero return rc;
886*042d53a7SEvalZero }
887*042d53a7SEvalZero
888*042d53a7SEvalZero phy_coded_params.max_ce_len = parse_arg_uint16_dflt("coded_max_conn_event",
889*042d53a7SEvalZero 0x0300, &rc);
890*042d53a7SEvalZero if (rc != 0) {
891*042d53a7SEvalZero console_printf("invalid 'coded_max_conn_event' parameter\n");
892*042d53a7SEvalZero return rc;
893*042d53a7SEvalZero }
894*042d53a7SEvalZero
895*042d53a7SEvalZero /* Get 2M params */
896*042d53a7SEvalZero phy_2M_params.itvl_min = parse_arg_uint16_dflt("2M_interval_min",
897*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MIN,
898*042d53a7SEvalZero &rc);
899*042d53a7SEvalZero if (rc != 0) {
900*042d53a7SEvalZero console_printf("invalid '2M_interval_min' parameter\n");
901*042d53a7SEvalZero return rc;
902*042d53a7SEvalZero }
903*042d53a7SEvalZero
904*042d53a7SEvalZero phy_2M_params.itvl_max = parse_arg_uint16_dflt("2M_interval_max",
905*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MAX, &rc);
906*042d53a7SEvalZero if (rc != 0) {
907*042d53a7SEvalZero console_printf("invalid '2M_interval_max' parameter\n");
908*042d53a7SEvalZero return rc;
909*042d53a7SEvalZero }
910*042d53a7SEvalZero
911*042d53a7SEvalZero phy_2M_params.latency =
912*042d53a7SEvalZero parse_arg_uint16_dflt("2M_latency", 0, &rc);
913*042d53a7SEvalZero if (rc != 0) {
914*042d53a7SEvalZero console_printf("invalid '2M_latency' parameter\n");
915*042d53a7SEvalZero return rc;
916*042d53a7SEvalZero }
917*042d53a7SEvalZero
918*042d53a7SEvalZero phy_2M_params.supervision_timeout = parse_arg_uint16_dflt("2M_timeout",
919*042d53a7SEvalZero 0x0100, &rc);
920*042d53a7SEvalZero
921*042d53a7SEvalZero if (rc != 0) {
922*042d53a7SEvalZero console_printf("invalid '2M_timeout' parameter\n");
923*042d53a7SEvalZero return rc;
924*042d53a7SEvalZero }
925*042d53a7SEvalZero
926*042d53a7SEvalZero phy_2M_params.min_ce_len = parse_arg_uint16_dflt("2M_min_conn_event", 0x0010,
927*042d53a7SEvalZero &rc);
928*042d53a7SEvalZero if (rc != 0) {
929*042d53a7SEvalZero console_printf("invalid '2M_min_conn_event' parameter\n");
930*042d53a7SEvalZero return rc;
931*042d53a7SEvalZero }
932*042d53a7SEvalZero
933*042d53a7SEvalZero phy_2M_params.max_ce_len = parse_arg_uint16_dflt("2M_max_conn_event",
934*042d53a7SEvalZero 0x0300, &rc);
935*042d53a7SEvalZero if (rc != 0) {
936*042d53a7SEvalZero console_printf("invalid '2M_max_conn_event' parameter\n");
937*042d53a7SEvalZero return rc;
938*042d53a7SEvalZero }
939*042d53a7SEvalZero
940*042d53a7SEvalZero if (ext == 0x02) {
941*042d53a7SEvalZero rc = btshell_ext_conn_initiate(own_addr_type, peer_addr_param,
942*042d53a7SEvalZero duration_ms, NULL, NULL, &phy_coded_params);
943*042d53a7SEvalZero return rc;
944*042d53a7SEvalZero }
945*042d53a7SEvalZero
946*042d53a7SEvalZero if (ext == 0x03) {
947*042d53a7SEvalZero rc = btshell_ext_conn_initiate(own_addr_type, peer_addr_param,
948*042d53a7SEvalZero duration_ms, &phy_1M_params, NULL,
949*042d53a7SEvalZero &phy_coded_params);
950*042d53a7SEvalZero return rc;
951*042d53a7SEvalZero }
952*042d53a7SEvalZero
953*042d53a7SEvalZero rc = btshell_ext_conn_initiate(own_addr_type, peer_addr_param,
954*042d53a7SEvalZero duration_ms, &phy_1M_params,
955*042d53a7SEvalZero &phy_2M_params,
956*042d53a7SEvalZero &phy_coded_params);
957*042d53a7SEvalZero return rc;
958*042d53a7SEvalZero }
959*042d53a7SEvalZero
960*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
961*042d53a7SEvalZero static const struct shell_param connect_params[] = {
962*042d53a7SEvalZero {"cancel", "cancel connection procedure"},
963*042d53a7SEvalZero {"extended", "usage: =[none|1M|coded|both|all], default: none"},
964*042d53a7SEvalZero {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
965*042d53a7SEvalZero {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
966*042d53a7SEvalZero {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
967*042d53a7SEvalZero {"duration", "usage: =[1-INT32_MAX], default: 0"},
968*042d53a7SEvalZero {"scan_interval", "usage: =[0-UINT16_MAX], default: 0x0010"},
969*042d53a7SEvalZero {"scan_window", "usage: =[0-UINT16_MAX], default: 0x0010"},
970*042d53a7SEvalZero {"interval_min", "usage: =[0-UINT16_MAX], default: 30"},
971*042d53a7SEvalZero {"interval_max", "usage: =[0-UINT16_MAX], default: 50"},
972*042d53a7SEvalZero {"latency", "usage: =[UINT16], default: 0"},
973*042d53a7SEvalZero {"timeout", "usage: =[UINT16], default: 0x0100"},
974*042d53a7SEvalZero {"min_conn_event_len", "usage: =[UINT16], default: 0x0010"},
975*042d53a7SEvalZero {"max_conn_event_len", "usage: =[UINT16], default: 0x0300"},
976*042d53a7SEvalZero {"coded_scan_interval", "usage: =[0-UINT16_MAX], default: 0x0010"},
977*042d53a7SEvalZero {"coded_scan_window", "usage: =[0-UINT16_MAX], default: 0x0010"},
978*042d53a7SEvalZero {"coded_interval_min", "usage: =[0-UINT16_MAX], default: 30"},
979*042d53a7SEvalZero {"coded_interval_max", "usage: =[0-UINT16_MAX], default: 50"},
980*042d53a7SEvalZero {"coded_latency", "usage: =[UINT16], default: 0"},
981*042d53a7SEvalZero {"coded_timeout", "usage: =[UINT16], default: 0x0100"},
982*042d53a7SEvalZero {"coded_min_conn_event_len", "usage: =[UINT16], default: 0x0010"},
983*042d53a7SEvalZero {"coded_max_conn_event_len", "usage: =[UINT16], default: 0x0300"},
984*042d53a7SEvalZero {"2M_interval_min", "usage: =[0-UINT16_MAX], default: 30"},
985*042d53a7SEvalZero {"2M_interval_max", "usage: =[0-UINT16_MAX], default: 50"},
986*042d53a7SEvalZero {"2M_latency", "usage: =[UINT16], default: 0"},
987*042d53a7SEvalZero {"2M_timeout", "usage: =[UINT16], default: 0x0100"},
988*042d53a7SEvalZero {"2M_min_conn_event_len", "usage: =[UINT16], default: 0x0010"},
989*042d53a7SEvalZero {"2M_max_conn_event_len", "usage: =[UINT16], default: 0x0300"},
990*042d53a7SEvalZero {NULL, NULL}
991*042d53a7SEvalZero };
992*042d53a7SEvalZero
993*042d53a7SEvalZero static const struct shell_cmd_help connect_help = {
994*042d53a7SEvalZero .summary = "start/stop connection procedure with specific parameters",
995*042d53a7SEvalZero .usage = NULL,
996*042d53a7SEvalZero .params = connect_params,
997*042d53a7SEvalZero };
998*042d53a7SEvalZero #endif
999*042d53a7SEvalZero
1000*042d53a7SEvalZero /*****************************************************************************
1001*042d53a7SEvalZero * $disconnect *
1002*042d53a7SEvalZero *****************************************************************************/
1003*042d53a7SEvalZero
1004*042d53a7SEvalZero static int
cmd_disconnect(int argc,char ** argv)1005*042d53a7SEvalZero cmd_disconnect(int argc, char **argv)
1006*042d53a7SEvalZero {
1007*042d53a7SEvalZero uint16_t conn_handle;
1008*042d53a7SEvalZero uint8_t reason;
1009*042d53a7SEvalZero int rc;
1010*042d53a7SEvalZero
1011*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1012*042d53a7SEvalZero if (rc != 0) {
1013*042d53a7SEvalZero return rc;
1014*042d53a7SEvalZero }
1015*042d53a7SEvalZero
1016*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
1017*042d53a7SEvalZero if (rc != 0) {
1018*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
1019*042d53a7SEvalZero return rc;
1020*042d53a7SEvalZero }
1021*042d53a7SEvalZero
1022*042d53a7SEvalZero reason = parse_arg_uint8_dflt("reason", BLE_ERR_REM_USER_CONN_TERM, &rc);
1023*042d53a7SEvalZero if (rc != 0) {
1024*042d53a7SEvalZero console_printf("invalid 'reason' parameter\n");
1025*042d53a7SEvalZero return rc;
1026*042d53a7SEvalZero }
1027*042d53a7SEvalZero
1028*042d53a7SEvalZero rc = btshell_term_conn(conn_handle, reason);
1029*042d53a7SEvalZero if (rc != 0) {
1030*042d53a7SEvalZero console_printf("error terminating connection; rc=%d\n", rc);
1031*042d53a7SEvalZero return rc;
1032*042d53a7SEvalZero }
1033*042d53a7SEvalZero
1034*042d53a7SEvalZero return 0;
1035*042d53a7SEvalZero }
1036*042d53a7SEvalZero
1037*042d53a7SEvalZero static int
cmd_show_conn(int argc,char ** argv)1038*042d53a7SEvalZero cmd_show_conn(int argc, char **argv)
1039*042d53a7SEvalZero {
1040*042d53a7SEvalZero struct ble_gap_conn_desc conn_desc;
1041*042d53a7SEvalZero struct btshell_conn *conn;
1042*042d53a7SEvalZero int rc;
1043*042d53a7SEvalZero int i;
1044*042d53a7SEvalZero
1045*042d53a7SEvalZero for (i = 0; i < btshell_num_conns; i++) {
1046*042d53a7SEvalZero conn = btshell_conns + i;
1047*042d53a7SEvalZero
1048*042d53a7SEvalZero rc = ble_gap_conn_find(conn->handle, &conn_desc);
1049*042d53a7SEvalZero if (rc == 0) {
1050*042d53a7SEvalZero print_conn_desc(&conn_desc);
1051*042d53a7SEvalZero }
1052*042d53a7SEvalZero }
1053*042d53a7SEvalZero
1054*042d53a7SEvalZero return 0;
1055*042d53a7SEvalZero }
1056*042d53a7SEvalZero
1057*042d53a7SEvalZero static int
cmd_show_addr(int argc,char ** argv)1058*042d53a7SEvalZero cmd_show_addr(int argc, char **argv)
1059*042d53a7SEvalZero {
1060*042d53a7SEvalZero uint8_t id_addr[6];
1061*042d53a7SEvalZero int rc;
1062*042d53a7SEvalZero
1063*042d53a7SEvalZero console_printf("public_id_addr=");
1064*042d53a7SEvalZero rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, id_addr, NULL);
1065*042d53a7SEvalZero if (rc == 0) {
1066*042d53a7SEvalZero print_addr(id_addr);
1067*042d53a7SEvalZero } else {
1068*042d53a7SEvalZero console_printf("none");
1069*042d53a7SEvalZero }
1070*042d53a7SEvalZero
1071*042d53a7SEvalZero console_printf(" random_id_addr=");
1072*042d53a7SEvalZero rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, id_addr, NULL);
1073*042d53a7SEvalZero if (rc == 0) {
1074*042d53a7SEvalZero print_addr(id_addr);
1075*042d53a7SEvalZero } else {
1076*042d53a7SEvalZero console_printf("none");
1077*042d53a7SEvalZero }
1078*042d53a7SEvalZero console_printf("\n");
1079*042d53a7SEvalZero
1080*042d53a7SEvalZero return 0;
1081*042d53a7SEvalZero }
1082*042d53a7SEvalZero
1083*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1084*042d53a7SEvalZero static const struct shell_param disconnect_params[] = {
1085*042d53a7SEvalZero {"conn", "connection handle parameter, usage: =<UINT16>"},
1086*042d53a7SEvalZero {"reason", "disconnection reason, usage: =[UINT8], default: 19 (remote user terminated connection)"},
1087*042d53a7SEvalZero {NULL, NULL}
1088*042d53a7SEvalZero };
1089*042d53a7SEvalZero
1090*042d53a7SEvalZero static const struct shell_cmd_help disconnect_help = {
1091*042d53a7SEvalZero .summary = "disconnect command",
1092*042d53a7SEvalZero .usage = NULL,
1093*042d53a7SEvalZero .params = disconnect_params,
1094*042d53a7SEvalZero };
1095*042d53a7SEvalZero #endif
1096*042d53a7SEvalZero
1097*042d53a7SEvalZero /*****************************************************************************
1098*042d53a7SEvalZero * $set-scan-opts *
1099*042d53a7SEvalZero *****************************************************************************/
1100*042d53a7SEvalZero
1101*042d53a7SEvalZero static struct btshell_scan_opts g_scan_opts = {
1102*042d53a7SEvalZero .limit = UINT16_MAX,
1103*042d53a7SEvalZero .ignore_legacy = 0,
1104*042d53a7SEvalZero };
1105*042d53a7SEvalZero
1106*042d53a7SEvalZero static int
cmd_set_scan_opts(int argc,char ** argv)1107*042d53a7SEvalZero cmd_set_scan_opts(int argc, char **argv)
1108*042d53a7SEvalZero {
1109*042d53a7SEvalZero int rc;
1110*042d53a7SEvalZero
1111*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1112*042d53a7SEvalZero if (rc != 0) {
1113*042d53a7SEvalZero return rc;
1114*042d53a7SEvalZero }
1115*042d53a7SEvalZero
1116*042d53a7SEvalZero g_scan_opts.limit = parse_arg_uint16_dflt("decode_limit", UINT16_MAX, &rc);
1117*042d53a7SEvalZero if (rc != 0) {
1118*042d53a7SEvalZero console_printf("invalid 'decode_limit' parameter\n");
1119*042d53a7SEvalZero return rc;
1120*042d53a7SEvalZero }
1121*042d53a7SEvalZero
1122*042d53a7SEvalZero g_scan_opts.ignore_legacy = parse_arg_bool_dflt("ignore_legacy", 0, &rc);
1123*042d53a7SEvalZero if (rc != 0) {
1124*042d53a7SEvalZero console_printf("invalid 'ignore_legacy' parameter\n");
1125*042d53a7SEvalZero return rc;
1126*042d53a7SEvalZero }
1127*042d53a7SEvalZero
1128*042d53a7SEvalZero return rc;
1129*042d53a7SEvalZero }
1130*042d53a7SEvalZero
1131*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1132*042d53a7SEvalZero static const struct shell_param set_scan_opts_params[] = {
1133*042d53a7SEvalZero {"decode_limit", "usage: =[0-UINT16_MAX], default: UINT16_MAX"},
1134*042d53a7SEvalZero {"ignore_legacy", "usage: =[0-1], default: 0"},
1135*042d53a7SEvalZero {NULL, NULL}
1136*042d53a7SEvalZero };
1137*042d53a7SEvalZero
1138*042d53a7SEvalZero static const struct shell_cmd_help set_scan_opts_help = {
1139*042d53a7SEvalZero .summary = "set scan options",
1140*042d53a7SEvalZero .usage = NULL,
1141*042d53a7SEvalZero .params = set_scan_opts_params,
1142*042d53a7SEvalZero };
1143*042d53a7SEvalZero #endif
1144*042d53a7SEvalZero
1145*042d53a7SEvalZero /*****************************************************************************
1146*042d53a7SEvalZero * $scan *
1147*042d53a7SEvalZero *****************************************************************************/
1148*042d53a7SEvalZero
1149*042d53a7SEvalZero static const struct kv_pair cmd_scan_filt_policies[] = {
1150*042d53a7SEvalZero { "no_wl", BLE_HCI_SCAN_FILT_NO_WL },
1151*042d53a7SEvalZero { "use_wl", BLE_HCI_SCAN_FILT_USE_WL },
1152*042d53a7SEvalZero { "no_wl_inita", BLE_HCI_SCAN_FILT_NO_WL_INITA },
1153*042d53a7SEvalZero { "use_wl_inita", BLE_HCI_SCAN_FILT_USE_WL_INITA },
1154*042d53a7SEvalZero { NULL }
1155*042d53a7SEvalZero };
1156*042d53a7SEvalZero
1157*042d53a7SEvalZero static struct kv_pair cmd_scan_ext_types[] = {
1158*042d53a7SEvalZero { "none", 0x00 },
1159*042d53a7SEvalZero { "1M", 0x01 },
1160*042d53a7SEvalZero { "coded", 0x02 },
1161*042d53a7SEvalZero { "both", 0x03 },
1162*042d53a7SEvalZero { NULL }
1163*042d53a7SEvalZero };
1164*042d53a7SEvalZero
1165*042d53a7SEvalZero static struct btshell_scan_opts g_scan_opts;
1166*042d53a7SEvalZero
1167*042d53a7SEvalZero static int
cmd_scan(int argc,char ** argv)1168*042d53a7SEvalZero cmd_scan(int argc, char **argv)
1169*042d53a7SEvalZero {
1170*042d53a7SEvalZero struct ble_gap_disc_params params = {0};
1171*042d53a7SEvalZero struct ble_gap_ext_disc_params uncoded = {0};
1172*042d53a7SEvalZero struct ble_gap_ext_disc_params coded = {0};
1173*042d53a7SEvalZero uint8_t extended;
1174*042d53a7SEvalZero int32_t duration_ms;
1175*042d53a7SEvalZero uint8_t own_addr_type;
1176*042d53a7SEvalZero uint16_t duration;
1177*042d53a7SEvalZero uint16_t period;
1178*042d53a7SEvalZero int rc;
1179*042d53a7SEvalZero
1180*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1181*042d53a7SEvalZero if (rc != 0) {
1182*042d53a7SEvalZero return rc;
1183*042d53a7SEvalZero }
1184*042d53a7SEvalZero
1185*042d53a7SEvalZero if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
1186*042d53a7SEvalZero rc = btshell_scan_cancel();
1187*042d53a7SEvalZero if (rc != 0) {
1188*042d53a7SEvalZero console_printf("scan cancel fail: %d\n", rc);
1189*042d53a7SEvalZero return rc;
1190*042d53a7SEvalZero }
1191*042d53a7SEvalZero return 0;
1192*042d53a7SEvalZero }
1193*042d53a7SEvalZero
1194*042d53a7SEvalZero extended = parse_arg_kv_dflt("extended", cmd_scan_ext_types, 0, &rc);
1195*042d53a7SEvalZero if (rc != 0) {
1196*042d53a7SEvalZero console_printf("invalid 'extended' parameter\n");
1197*042d53a7SEvalZero return rc;
1198*042d53a7SEvalZero }
1199*042d53a7SEvalZero
1200*042d53a7SEvalZero duration_ms = parse_arg_long_bounds_dflt("duration", 1, INT32_MAX,
1201*042d53a7SEvalZero BLE_HS_FOREVER, &rc);
1202*042d53a7SEvalZero if (rc != 0) {
1203*042d53a7SEvalZero console_printf("invalid 'duration' parameter\n");
1204*042d53a7SEvalZero return rc;
1205*042d53a7SEvalZero }
1206*042d53a7SEvalZero
1207*042d53a7SEvalZero params.limited = parse_arg_bool_dflt("limited", 0, &rc);
1208*042d53a7SEvalZero if (rc != 0) {
1209*042d53a7SEvalZero console_printf("invalid 'limited' parameter\n");
1210*042d53a7SEvalZero return rc;
1211*042d53a7SEvalZero }
1212*042d53a7SEvalZero
1213*042d53a7SEvalZero params.passive = parse_arg_bool_dflt("passive", 0, &rc);
1214*042d53a7SEvalZero if (rc != 0) {
1215*042d53a7SEvalZero console_printf("invalid 'passive' parameter\n");
1216*042d53a7SEvalZero return rc;
1217*042d53a7SEvalZero }
1218*042d53a7SEvalZero
1219*042d53a7SEvalZero params.itvl = parse_arg_uint16_dflt("interval", 0, &rc);
1220*042d53a7SEvalZero if (rc != 0) {
1221*042d53a7SEvalZero console_printf("invalid 'interval' parameter\n");
1222*042d53a7SEvalZero return rc;
1223*042d53a7SEvalZero }
1224*042d53a7SEvalZero
1225*042d53a7SEvalZero params.window = parse_arg_uint16_dflt("window", 0, &rc);
1226*042d53a7SEvalZero if (rc != 0) {
1227*042d53a7SEvalZero console_printf("invalid 'window' parameter\n");
1228*042d53a7SEvalZero return rc;
1229*042d53a7SEvalZero }
1230*042d53a7SEvalZero
1231*042d53a7SEvalZero params.filter_policy = parse_arg_kv_dflt("filter", cmd_scan_filt_policies,
1232*042d53a7SEvalZero BLE_HCI_SCAN_FILT_NO_WL, &rc);
1233*042d53a7SEvalZero if (rc != 0) {
1234*042d53a7SEvalZero console_printf("invalid 'filter' parameter\n");
1235*042d53a7SEvalZero return rc;
1236*042d53a7SEvalZero }
1237*042d53a7SEvalZero
1238*042d53a7SEvalZero params.filter_duplicates = parse_arg_bool_dflt("nodups", 0, &rc);
1239*042d53a7SEvalZero if (rc != 0) {
1240*042d53a7SEvalZero console_printf("invalid 'nodups' parameter\n");
1241*042d53a7SEvalZero return rc;
1242*042d53a7SEvalZero }
1243*042d53a7SEvalZero
1244*042d53a7SEvalZero own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types,
1245*042d53a7SEvalZero BLE_OWN_ADDR_PUBLIC, &rc);
1246*042d53a7SEvalZero if (rc != 0) {
1247*042d53a7SEvalZero console_printf("invalid 'own_addr_type' parameter\n");
1248*042d53a7SEvalZero return rc;
1249*042d53a7SEvalZero }
1250*042d53a7SEvalZero
1251*042d53a7SEvalZero if (extended == 0) {
1252*042d53a7SEvalZero rc = btshell_scan(own_addr_type, duration_ms, ¶ms, &g_scan_opts);
1253*042d53a7SEvalZero if (rc != 0) {
1254*042d53a7SEvalZero console_printf("error scanning; rc=%d\n", rc);
1255*042d53a7SEvalZero return rc;
1256*042d53a7SEvalZero }
1257*042d53a7SEvalZero
1258*042d53a7SEvalZero return 0;
1259*042d53a7SEvalZero }
1260*042d53a7SEvalZero
1261*042d53a7SEvalZero /* Copy above parameters to uncoded params */
1262*042d53a7SEvalZero uncoded.passive = params.passive;
1263*042d53a7SEvalZero uncoded.itvl = params.itvl;
1264*042d53a7SEvalZero uncoded.window = params.window;
1265*042d53a7SEvalZero
1266*042d53a7SEvalZero duration = parse_arg_uint16_dflt("extended_duration", 0, &rc);
1267*042d53a7SEvalZero if (rc != 0) {
1268*042d53a7SEvalZero console_printf("invalid 'extended_duration' parameter\n");
1269*042d53a7SEvalZero return rc;
1270*042d53a7SEvalZero }
1271*042d53a7SEvalZero
1272*042d53a7SEvalZero period = parse_arg_uint16_dflt("extended_period", 0, &rc);
1273*042d53a7SEvalZero if (rc != 0) {
1274*042d53a7SEvalZero console_printf("invalid 'extended_period' parameter\n");
1275*042d53a7SEvalZero return rc;
1276*042d53a7SEvalZero }
1277*042d53a7SEvalZero
1278*042d53a7SEvalZero coded.itvl = parse_arg_uint16_dflt("longrange_interval", 0, &rc);
1279*042d53a7SEvalZero if (rc != 0) {
1280*042d53a7SEvalZero console_printf("invalid 'longrange_interval' parameter\n");
1281*042d53a7SEvalZero return rc;
1282*042d53a7SEvalZero }
1283*042d53a7SEvalZero
1284*042d53a7SEvalZero coded.window = parse_arg_uint16_dflt("longrange_window", 0, &rc);
1285*042d53a7SEvalZero if (rc != 0) {
1286*042d53a7SEvalZero console_printf("invalid 'longrange_window' parameter\n");
1287*042d53a7SEvalZero return rc;
1288*042d53a7SEvalZero }
1289*042d53a7SEvalZero
1290*042d53a7SEvalZero coded.passive = parse_arg_uint16_dflt("longrange_passive", 0, &rc);
1291*042d53a7SEvalZero if (rc != 0) {
1292*042d53a7SEvalZero console_printf("invalid 'longrange_passive' parameter\n");
1293*042d53a7SEvalZero return rc;
1294*042d53a7SEvalZero }
1295*042d53a7SEvalZero
1296*042d53a7SEvalZero switch (extended) {
1297*042d53a7SEvalZero case 0x01:
1298*042d53a7SEvalZero rc = btshell_ext_scan(own_addr_type, duration, period,
1299*042d53a7SEvalZero params.filter_duplicates, params.filter_policy,
1300*042d53a7SEvalZero params.limited, &uncoded, NULL,
1301*042d53a7SEvalZero &g_scan_opts);
1302*042d53a7SEvalZero break;
1303*042d53a7SEvalZero case 0x02:
1304*042d53a7SEvalZero rc = btshell_ext_scan(own_addr_type, duration, period,
1305*042d53a7SEvalZero params.filter_duplicates, params.filter_policy,
1306*042d53a7SEvalZero params.limited, NULL, &coded,
1307*042d53a7SEvalZero &g_scan_opts);
1308*042d53a7SEvalZero break;
1309*042d53a7SEvalZero case 0x03:
1310*042d53a7SEvalZero rc = btshell_ext_scan(own_addr_type, duration, period,
1311*042d53a7SEvalZero params.filter_duplicates, params.filter_policy,
1312*042d53a7SEvalZero params.limited, &uncoded, &coded,
1313*042d53a7SEvalZero &g_scan_opts);
1314*042d53a7SEvalZero break;
1315*042d53a7SEvalZero default:
1316*042d53a7SEvalZero rc = -1;
1317*042d53a7SEvalZero console_printf("invalid 'extended' parameter\n");
1318*042d53a7SEvalZero break;
1319*042d53a7SEvalZero }
1320*042d53a7SEvalZero
1321*042d53a7SEvalZero return rc;
1322*042d53a7SEvalZero }
1323*042d53a7SEvalZero
1324*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1325*042d53a7SEvalZero static const struct shell_param scan_params[] = {
1326*042d53a7SEvalZero {"cancel", "cancel scan procedure"},
1327*042d53a7SEvalZero {"extended", "usage: =[none|1M|coded|both], default: none"},
1328*042d53a7SEvalZero {"duration", "usage: =[1-INT32_MAX], default: INT32_MAX"},
1329*042d53a7SEvalZero {"limited", "usage: =[0-1], default: 0"},
1330*042d53a7SEvalZero {"passive", "usage: =[0-1], default: 0"},
1331*042d53a7SEvalZero {"interval", "usage: =[0-UINT16_MAX], default: 0"},
1332*042d53a7SEvalZero {"window", "usage: =[0-UINT16_MAX], default: 0"},
1333*042d53a7SEvalZero {"filter", "usage: =[no_wl|use_wl|no_wl_inita|use_wl_inita], default: no_wl"},
1334*042d53a7SEvalZero {"nodups", "usage: =[0-1], default: 0"},
1335*042d53a7SEvalZero {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"},
1336*042d53a7SEvalZero {"extended_duration", "usage: =[0-UINT16_MAX], default: 0"},
1337*042d53a7SEvalZero {"extended_period", "usage: =[0-UINT16_MAX], default: 0"},
1338*042d53a7SEvalZero {"longrange_interval", "usage: =[0-UINT16_MAX], default: 0"},
1339*042d53a7SEvalZero {"longrange_window", "usage: =[0-UINT16_MAX], default: 0"},
1340*042d53a7SEvalZero {"longrange_passive", "usage: =[0-1], default: 0"},
1341*042d53a7SEvalZero {NULL, NULL}
1342*042d53a7SEvalZero };
1343*042d53a7SEvalZero
1344*042d53a7SEvalZero static const struct shell_cmd_help scan_help = {
1345*042d53a7SEvalZero .summary = "start/stop scan procedure with specific parameters",
1346*042d53a7SEvalZero .usage = NULL,
1347*042d53a7SEvalZero .params = scan_params,
1348*042d53a7SEvalZero };
1349*042d53a7SEvalZero #endif
1350*042d53a7SEvalZero
1351*042d53a7SEvalZero /*****************************************************************************
1352*042d53a7SEvalZero * $set *
1353*042d53a7SEvalZero *****************************************************************************/
1354*042d53a7SEvalZero
1355*042d53a7SEvalZero static const struct kv_pair cmd_set_addr_types[] = {
1356*042d53a7SEvalZero { "public", BLE_ADDR_PUBLIC },
1357*042d53a7SEvalZero { "random", BLE_ADDR_RANDOM },
1358*042d53a7SEvalZero { NULL }
1359*042d53a7SEvalZero };
1360*042d53a7SEvalZero
1361*042d53a7SEvalZero static int
cmd_set_addr(void)1362*042d53a7SEvalZero cmd_set_addr(void)
1363*042d53a7SEvalZero {
1364*042d53a7SEvalZero uint8_t addr[6];
1365*042d53a7SEvalZero int addr_type;
1366*042d53a7SEvalZero int rc;
1367*042d53a7SEvalZero
1368*042d53a7SEvalZero addr_type = parse_arg_kv_dflt("addr_type", cmd_set_addr_types,
1369*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
1370*042d53a7SEvalZero if (rc != 0) {
1371*042d53a7SEvalZero console_printf("invalid 'addr_type' parameter\n");
1372*042d53a7SEvalZero return rc;
1373*042d53a7SEvalZero }
1374*042d53a7SEvalZero
1375*042d53a7SEvalZero rc = parse_arg_mac("addr", addr);
1376*042d53a7SEvalZero if (rc != 0) {
1377*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
1378*042d53a7SEvalZero return rc;
1379*042d53a7SEvalZero }
1380*042d53a7SEvalZero
1381*042d53a7SEvalZero switch (addr_type) {
1382*042d53a7SEvalZero #if MYNEWT_VAL(BLE_DEVICE)
1383*042d53a7SEvalZero case BLE_ADDR_PUBLIC:
1384*042d53a7SEvalZero /* We shouldn't be writing to the controller's address (g_dev_addr).
1385*042d53a7SEvalZero * There is no standard way to set the local public address, so this is
1386*042d53a7SEvalZero * our only option at the moment.
1387*042d53a7SEvalZero */
1388*042d53a7SEvalZero memcpy(g_dev_addr, addr, 6);
1389*042d53a7SEvalZero ble_hs_id_set_pub(g_dev_addr);
1390*042d53a7SEvalZero break;
1391*042d53a7SEvalZero #endif
1392*042d53a7SEvalZero
1393*042d53a7SEvalZero case BLE_ADDR_RANDOM:
1394*042d53a7SEvalZero rc = ble_hs_id_set_rnd(addr);
1395*042d53a7SEvalZero if (rc != 0) {
1396*042d53a7SEvalZero return rc;
1397*042d53a7SEvalZero }
1398*042d53a7SEvalZero break;
1399*042d53a7SEvalZero
1400*042d53a7SEvalZero default:
1401*042d53a7SEvalZero return BLE_HS_EUNKNOWN;
1402*042d53a7SEvalZero }
1403*042d53a7SEvalZero
1404*042d53a7SEvalZero return 0;
1405*042d53a7SEvalZero }
1406*042d53a7SEvalZero
1407*042d53a7SEvalZero static int
cmd_set(int argc,char ** argv)1408*042d53a7SEvalZero cmd_set(int argc, char **argv)
1409*042d53a7SEvalZero {
1410*042d53a7SEvalZero uint16_t mtu;
1411*042d53a7SEvalZero uint8_t irk[16];
1412*042d53a7SEvalZero int good = 0;
1413*042d53a7SEvalZero int rc;
1414*042d53a7SEvalZero
1415*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1416*042d53a7SEvalZero if (rc != 0) {
1417*042d53a7SEvalZero return rc;
1418*042d53a7SEvalZero }
1419*042d53a7SEvalZero
1420*042d53a7SEvalZero rc = parse_arg_find_idx("addr");
1421*042d53a7SEvalZero if (rc != -1) {
1422*042d53a7SEvalZero rc = cmd_set_addr();
1423*042d53a7SEvalZero if (rc != 0) {
1424*042d53a7SEvalZero return rc;
1425*042d53a7SEvalZero }
1426*042d53a7SEvalZero good = 1;
1427*042d53a7SEvalZero }
1428*042d53a7SEvalZero
1429*042d53a7SEvalZero mtu = parse_arg_uint16("mtu", &rc);
1430*042d53a7SEvalZero if (rc == 0) {
1431*042d53a7SEvalZero rc = ble_att_set_preferred_mtu(mtu);
1432*042d53a7SEvalZero if (rc == 0) {
1433*042d53a7SEvalZero good = 1;
1434*042d53a7SEvalZero }
1435*042d53a7SEvalZero } else if (rc != ENOENT) {
1436*042d53a7SEvalZero console_printf("invalid 'mtu' parameter\n");
1437*042d53a7SEvalZero return rc;
1438*042d53a7SEvalZero }
1439*042d53a7SEvalZero
1440*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("irk", irk, 16);
1441*042d53a7SEvalZero if (rc == 0) {
1442*042d53a7SEvalZero good = 1;
1443*042d53a7SEvalZero ble_hs_pvcy_set_our_irk(irk);
1444*042d53a7SEvalZero } else if (rc != ENOENT) {
1445*042d53a7SEvalZero console_printf("invalid 'irk' parameter\n");
1446*042d53a7SEvalZero return rc;
1447*042d53a7SEvalZero }
1448*042d53a7SEvalZero
1449*042d53a7SEvalZero if (!good) {
1450*042d53a7SEvalZero console_printf("Error: no valid settings specified\n");
1451*042d53a7SEvalZero return -1;
1452*042d53a7SEvalZero }
1453*042d53a7SEvalZero
1454*042d53a7SEvalZero return 0;
1455*042d53a7SEvalZero }
1456*042d53a7SEvalZero
1457*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1458*042d53a7SEvalZero static const struct shell_param set_params[] = {
1459*042d53a7SEvalZero {"addr", "set device address, usage: =[XX:XX:XX:XX:XX:XX]"},
1460*042d53a7SEvalZero {"addr_type", "set device address type, usage: =[public|random], default: public"},
1461*042d53a7SEvalZero {"mtu", "Maximum Transimssion Unit, usage: =[0-UINT16_MAX]"},
1462*042d53a7SEvalZero {"irk", "Identity Resolving Key, usage: =[XX:XX...], len=16 octets"},
1463*042d53a7SEvalZero {NULL, NULL}
1464*042d53a7SEvalZero };
1465*042d53a7SEvalZero
1466*042d53a7SEvalZero static const struct shell_cmd_help set_help = {
1467*042d53a7SEvalZero .summary = "set device parameters",
1468*042d53a7SEvalZero .usage = NULL,
1469*042d53a7SEvalZero .params = set_params,
1470*042d53a7SEvalZero };
1471*042d53a7SEvalZero #endif
1472*042d53a7SEvalZero
1473*042d53a7SEvalZero /*****************************************************************************
1474*042d53a7SEvalZero * $set-adv-data *
1475*042d53a7SEvalZero *****************************************************************************/
1476*042d53a7SEvalZero
1477*042d53a7SEvalZero #define CMD_ADV_DATA_MAX_UUIDS16 8
1478*042d53a7SEvalZero #define CMD_ADV_DATA_MAX_UUIDS32 8
1479*042d53a7SEvalZero #define CMD_ADV_DATA_MAX_UUIDS128 2
1480*042d53a7SEvalZero #define CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS 8
1481*042d53a7SEvalZero #define CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN BLE_HS_ADV_MAX_FIELD_SZ
1482*042d53a7SEvalZero #define CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN BLE_HS_ADV_MAX_FIELD_SZ
1483*042d53a7SEvalZero #define CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN BLE_HS_ADV_MAX_FIELD_SZ
1484*042d53a7SEvalZero #define CMD_ADV_DATA_URI_MAX_LEN BLE_HS_ADV_MAX_FIELD_SZ
1485*042d53a7SEvalZero #define CMD_ADV_DATA_MFG_DATA_MAX_LEN BLE_HS_ADV_MAX_FIELD_SZ
1486*042d53a7SEvalZero
1487*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
1488*042d53a7SEvalZero static void
update_pattern(uint8_t * buf,int counter)1489*042d53a7SEvalZero update_pattern(uint8_t *buf, int counter)
1490*042d53a7SEvalZero {
1491*042d53a7SEvalZero int i;
1492*042d53a7SEvalZero
1493*042d53a7SEvalZero for (i = 0; i < 10; i += 2) {
1494*042d53a7SEvalZero counter += 2;
1495*042d53a7SEvalZero buf[i] = (counter / 1000) << 4 | (counter / 100 % 10);
1496*042d53a7SEvalZero buf[i + 1] = (counter / 10 % 10) << 4 | (counter % 10);
1497*042d53a7SEvalZero }
1498*042d53a7SEvalZero }
1499*042d53a7SEvalZero #endif
1500*042d53a7SEvalZero
1501*042d53a7SEvalZero static int
cmd_set_adv_data_or_scan_rsp(int argc,char ** argv,bool scan_rsp)1502*042d53a7SEvalZero cmd_set_adv_data_or_scan_rsp(int argc, char **argv, bool scan_rsp)
1503*042d53a7SEvalZero {
1504*042d53a7SEvalZero static bssnz_t ble_uuid16_t uuids16[CMD_ADV_DATA_MAX_UUIDS16];
1505*042d53a7SEvalZero static bssnz_t ble_uuid32_t uuids32[CMD_ADV_DATA_MAX_UUIDS32];
1506*042d53a7SEvalZero static bssnz_t ble_uuid128_t uuids128[CMD_ADV_DATA_MAX_UUIDS128];
1507*042d53a7SEvalZero static bssnz_t uint8_t
1508*042d53a7SEvalZero public_tgt_addrs[CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS]
1509*042d53a7SEvalZero [BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
1510*042d53a7SEvalZero static bssnz_t uint8_t slave_itvl_range[BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN];
1511*042d53a7SEvalZero static bssnz_t uint8_t
1512*042d53a7SEvalZero svc_data_uuid16[CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN];
1513*042d53a7SEvalZero static bssnz_t uint8_t
1514*042d53a7SEvalZero svc_data_uuid32[CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN];
1515*042d53a7SEvalZero static bssnz_t uint8_t
1516*042d53a7SEvalZero svc_data_uuid128[CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN];
1517*042d53a7SEvalZero static bssnz_t uint8_t uri[CMD_ADV_DATA_URI_MAX_LEN];
1518*042d53a7SEvalZero static bssnz_t uint8_t mfg_data[CMD_ADV_DATA_MFG_DATA_MAX_LEN];
1519*042d53a7SEvalZero struct ble_hs_adv_fields adv_fields;
1520*042d53a7SEvalZero uint32_t uuid32;
1521*042d53a7SEvalZero uint16_t uuid16;
1522*042d53a7SEvalZero uint8_t uuid128[16];
1523*042d53a7SEvalZero uint8_t public_tgt_addr[BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
1524*042d53a7SEvalZero uint8_t eddystone_url_body_len;
1525*042d53a7SEvalZero uint8_t eddystone_url_suffix;
1526*042d53a7SEvalZero uint8_t eddystone_url_scheme;
1527*042d53a7SEvalZero int8_t eddystone_measured_power = 0;
1528*042d53a7SEvalZero char eddystone_url_body[BLE_EDDYSTONE_URL_MAX_LEN];
1529*042d53a7SEvalZero char *eddystone_url_full;
1530*042d53a7SEvalZero int svc_data_uuid16_len;
1531*042d53a7SEvalZero int svc_data_uuid32_len;
1532*042d53a7SEvalZero int svc_data_uuid128_len;
1533*042d53a7SEvalZero int uri_len;
1534*042d53a7SEvalZero int mfg_data_len;
1535*042d53a7SEvalZero int tmp;
1536*042d53a7SEvalZero int rc;
1537*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
1538*042d53a7SEvalZero uint8_t instance;
1539*042d53a7SEvalZero uint8_t extra_data[10];
1540*042d53a7SEvalZero uint16_t counter;
1541*042d53a7SEvalZero uint16_t extra_data_len;
1542*042d53a7SEvalZero struct os_mbuf *adv_data;
1543*042d53a7SEvalZero #endif
1544*042d53a7SEvalZero
1545*042d53a7SEvalZero memset(&adv_fields, 0, sizeof adv_fields);
1546*042d53a7SEvalZero
1547*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1548*042d53a7SEvalZero if (rc != 0) {
1549*042d53a7SEvalZero return rc;
1550*042d53a7SEvalZero }
1551*042d53a7SEvalZero
1552*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
1553*042d53a7SEvalZero instance = parse_arg_uint8_dflt("instance", 0, &rc);
1554*042d53a7SEvalZero if (rc != 0 || instance >= BLE_ADV_INSTANCES) {
1555*042d53a7SEvalZero console_printf("invalid instance\n");
1556*042d53a7SEvalZero return rc;
1557*042d53a7SEvalZero }
1558*042d53a7SEvalZero
1559*042d53a7SEvalZero if (!adv_instances[instance]) {
1560*042d53a7SEvalZero console_printf("instance not configured\n");
1561*042d53a7SEvalZero return rc;
1562*042d53a7SEvalZero }
1563*042d53a7SEvalZero #endif
1564*042d53a7SEvalZero
1565*042d53a7SEvalZero tmp = parse_arg_uint8("flags", &rc);
1566*042d53a7SEvalZero if (rc == 0) {
1567*042d53a7SEvalZero adv_fields.flags = tmp;
1568*042d53a7SEvalZero } else if (rc != ENOENT) {
1569*042d53a7SEvalZero console_printf("invalid 'flags' parameter\n");
1570*042d53a7SEvalZero return rc;
1571*042d53a7SEvalZero }
1572*042d53a7SEvalZero
1573*042d53a7SEvalZero while (1) {
1574*042d53a7SEvalZero uuid16 = parse_arg_uint16("uuid16", &rc);
1575*042d53a7SEvalZero if (rc == 0) {
1576*042d53a7SEvalZero if (adv_fields.num_uuids16 >= CMD_ADV_DATA_MAX_UUIDS16) {
1577*042d53a7SEvalZero console_printf("invalid 'uuid16' parameter\n");
1578*042d53a7SEvalZero return EINVAL;
1579*042d53a7SEvalZero }
1580*042d53a7SEvalZero uuids16[adv_fields.num_uuids16] = (ble_uuid16_t) BLE_UUID16_INIT(uuid16);
1581*042d53a7SEvalZero adv_fields.num_uuids16++;
1582*042d53a7SEvalZero } else if (rc == ENOENT) {
1583*042d53a7SEvalZero break;
1584*042d53a7SEvalZero } else {
1585*042d53a7SEvalZero console_printf("invalid 'uuid16' parameter\n");
1586*042d53a7SEvalZero return rc;
1587*042d53a7SEvalZero }
1588*042d53a7SEvalZero }
1589*042d53a7SEvalZero if (adv_fields.num_uuids16 > 0) {
1590*042d53a7SEvalZero adv_fields.uuids16 = uuids16;
1591*042d53a7SEvalZero }
1592*042d53a7SEvalZero
1593*042d53a7SEvalZero tmp = parse_arg_bool_dflt("uuids16_is_complete", 0, &rc);
1594*042d53a7SEvalZero if (rc != 0) {
1595*042d53a7SEvalZero console_printf("invalid 'uuids16_is_complete' parameter\n");
1596*042d53a7SEvalZero return rc;
1597*042d53a7SEvalZero }
1598*042d53a7SEvalZero
1599*042d53a7SEvalZero while (1) {
1600*042d53a7SEvalZero uuid32 = parse_arg_uint32("uuid32", &rc);
1601*042d53a7SEvalZero if (rc == 0) {
1602*042d53a7SEvalZero if (adv_fields.num_uuids32 >= CMD_ADV_DATA_MAX_UUIDS32) {
1603*042d53a7SEvalZero console_printf("invalid 'uuid32' parameter\n");
1604*042d53a7SEvalZero return EINVAL;
1605*042d53a7SEvalZero }
1606*042d53a7SEvalZero uuids32[adv_fields.num_uuids32] = (ble_uuid32_t) BLE_UUID32_INIT(uuid32);
1607*042d53a7SEvalZero adv_fields.num_uuids32++;
1608*042d53a7SEvalZero } else if (rc == ENOENT) {
1609*042d53a7SEvalZero break;
1610*042d53a7SEvalZero } else {
1611*042d53a7SEvalZero console_printf("invalid 'uuid32' parameter\n");
1612*042d53a7SEvalZero return rc;
1613*042d53a7SEvalZero }
1614*042d53a7SEvalZero }
1615*042d53a7SEvalZero if (adv_fields.num_uuids32 > 0) {
1616*042d53a7SEvalZero adv_fields.uuids32 = uuids32;
1617*042d53a7SEvalZero }
1618*042d53a7SEvalZero
1619*042d53a7SEvalZero tmp = parse_arg_bool_dflt("uuids32_is_complete", 0, &rc);
1620*042d53a7SEvalZero if (rc != 0) {
1621*042d53a7SEvalZero console_printf("invalid 'uuids32_is_complete' parameter\n");
1622*042d53a7SEvalZero return rc;
1623*042d53a7SEvalZero }
1624*042d53a7SEvalZero
1625*042d53a7SEvalZero while (1) {
1626*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("uuid128", uuid128, 16);
1627*042d53a7SEvalZero if (rc == 0) {
1628*042d53a7SEvalZero if (adv_fields.num_uuids128 >= CMD_ADV_DATA_MAX_UUIDS128) {
1629*042d53a7SEvalZero console_printf("invalid 'uuid128' parameter\n");
1630*042d53a7SEvalZero return EINVAL;
1631*042d53a7SEvalZero }
1632*042d53a7SEvalZero ble_uuid_init_from_buf((ble_uuid_any_t *) &uuids128[adv_fields.num_uuids128],
1633*042d53a7SEvalZero uuid128, 16);
1634*042d53a7SEvalZero adv_fields.num_uuids128++;
1635*042d53a7SEvalZero } else if (rc == ENOENT) {
1636*042d53a7SEvalZero break;
1637*042d53a7SEvalZero } else {
1638*042d53a7SEvalZero console_printf("invalid 'uuid128' parameter\n");
1639*042d53a7SEvalZero return rc;
1640*042d53a7SEvalZero }
1641*042d53a7SEvalZero }
1642*042d53a7SEvalZero if (adv_fields.num_uuids128 > 0) {
1643*042d53a7SEvalZero adv_fields.uuids128 = uuids128;
1644*042d53a7SEvalZero }
1645*042d53a7SEvalZero
1646*042d53a7SEvalZero tmp = parse_arg_bool_dflt("uuids128_is_complete", 0, &rc);
1647*042d53a7SEvalZero if (rc != 0) {
1648*042d53a7SEvalZero console_printf("invalid 'uuids128_is_complete' parameter\n");
1649*042d53a7SEvalZero return rc;
1650*042d53a7SEvalZero }
1651*042d53a7SEvalZero
1652*042d53a7SEvalZero adv_fields.name = (uint8_t *)parse_arg_extract("name");
1653*042d53a7SEvalZero if (adv_fields.name != NULL) {
1654*042d53a7SEvalZero adv_fields.name_len = strlen((char *)adv_fields.name);
1655*042d53a7SEvalZero }
1656*042d53a7SEvalZero
1657*042d53a7SEvalZero tmp = parse_arg_long_bounds("tx_power_level", INT8_MIN, INT8_MAX, &rc);
1658*042d53a7SEvalZero if (rc == 0) {
1659*042d53a7SEvalZero adv_fields.tx_pwr_lvl = tmp;
1660*042d53a7SEvalZero adv_fields.tx_pwr_lvl_is_present = 1;
1661*042d53a7SEvalZero } else if (rc != ENOENT) {
1662*042d53a7SEvalZero console_printf("invalid 'tx_power_level' parameter\n");
1663*042d53a7SEvalZero return rc;
1664*042d53a7SEvalZero }
1665*042d53a7SEvalZero
1666*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("slave_interval_range",
1667*042d53a7SEvalZero slave_itvl_range,
1668*042d53a7SEvalZero BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
1669*042d53a7SEvalZero if (rc == 0) {
1670*042d53a7SEvalZero adv_fields.slave_itvl_range = slave_itvl_range;
1671*042d53a7SEvalZero } else if (rc != ENOENT) {
1672*042d53a7SEvalZero console_printf("invalid 'slave_interval_range' parameter\n");
1673*042d53a7SEvalZero return rc;
1674*042d53a7SEvalZero }
1675*042d53a7SEvalZero
1676*042d53a7SEvalZero rc = parse_arg_byte_stream("service_data_uuid16",
1677*042d53a7SEvalZero CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN,
1678*042d53a7SEvalZero svc_data_uuid16, &svc_data_uuid16_len);
1679*042d53a7SEvalZero if (rc == 0) {
1680*042d53a7SEvalZero adv_fields.svc_data_uuid16 = svc_data_uuid16;
1681*042d53a7SEvalZero adv_fields.svc_data_uuid16_len = svc_data_uuid16_len;
1682*042d53a7SEvalZero } else if (rc != ENOENT) {
1683*042d53a7SEvalZero console_printf("invalid 'service_data_uuid16' parameter\n");
1684*042d53a7SEvalZero return rc;
1685*042d53a7SEvalZero }
1686*042d53a7SEvalZero
1687*042d53a7SEvalZero while (1) {
1688*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length(
1689*042d53a7SEvalZero "public_target_address", public_tgt_addr,
1690*042d53a7SEvalZero BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
1691*042d53a7SEvalZero if (rc == 0) {
1692*042d53a7SEvalZero if (adv_fields.num_public_tgt_addrs >=
1693*042d53a7SEvalZero CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS) {
1694*042d53a7SEvalZero
1695*042d53a7SEvalZero console_printf("invalid 'public_target_address' parameter\n");
1696*042d53a7SEvalZero return EINVAL;
1697*042d53a7SEvalZero }
1698*042d53a7SEvalZero memcpy(public_tgt_addrs[adv_fields.num_public_tgt_addrs],
1699*042d53a7SEvalZero public_tgt_addr, BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
1700*042d53a7SEvalZero adv_fields.num_public_tgt_addrs++;
1701*042d53a7SEvalZero } else if (rc == ENOENT) {
1702*042d53a7SEvalZero break;
1703*042d53a7SEvalZero } else {
1704*042d53a7SEvalZero console_printf("invalid 'public_target_address' parameter\n");
1705*042d53a7SEvalZero return rc;
1706*042d53a7SEvalZero }
1707*042d53a7SEvalZero }
1708*042d53a7SEvalZero if (adv_fields.num_public_tgt_addrs > 0) {
1709*042d53a7SEvalZero adv_fields.public_tgt_addr = (void *)public_tgt_addrs;
1710*042d53a7SEvalZero }
1711*042d53a7SEvalZero
1712*042d53a7SEvalZero adv_fields.appearance = parse_arg_uint16("appearance", &rc);
1713*042d53a7SEvalZero if (rc == 0) {
1714*042d53a7SEvalZero adv_fields.appearance_is_present = 1;
1715*042d53a7SEvalZero } else if (rc != ENOENT) {
1716*042d53a7SEvalZero console_printf("invalid 'appearance' parameter\n");
1717*042d53a7SEvalZero return rc;
1718*042d53a7SEvalZero }
1719*042d53a7SEvalZero
1720*042d53a7SEvalZero adv_fields.adv_itvl = parse_arg_uint16("advertising_interval", &rc);
1721*042d53a7SEvalZero if (rc == 0) {
1722*042d53a7SEvalZero adv_fields.adv_itvl_is_present = 1;
1723*042d53a7SEvalZero } else if (rc != ENOENT) {
1724*042d53a7SEvalZero console_printf("invalid 'advertising_interval' parameter\n");
1725*042d53a7SEvalZero return rc;
1726*042d53a7SEvalZero }
1727*042d53a7SEvalZero
1728*042d53a7SEvalZero rc = parse_arg_byte_stream("service_data_uuid32",
1729*042d53a7SEvalZero CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN,
1730*042d53a7SEvalZero svc_data_uuid32, &svc_data_uuid32_len);
1731*042d53a7SEvalZero if (rc == 0) {
1732*042d53a7SEvalZero adv_fields.svc_data_uuid32 = svc_data_uuid32;
1733*042d53a7SEvalZero adv_fields.svc_data_uuid32_len = svc_data_uuid32_len;
1734*042d53a7SEvalZero } else if (rc != ENOENT) {
1735*042d53a7SEvalZero console_printf("invalid 'service_data_uuid32' parameter\n");
1736*042d53a7SEvalZero return rc;
1737*042d53a7SEvalZero }
1738*042d53a7SEvalZero
1739*042d53a7SEvalZero rc = parse_arg_byte_stream("service_data_uuid128",
1740*042d53a7SEvalZero CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN,
1741*042d53a7SEvalZero svc_data_uuid128, &svc_data_uuid128_len);
1742*042d53a7SEvalZero if (rc == 0) {
1743*042d53a7SEvalZero adv_fields.svc_data_uuid128 = svc_data_uuid128;
1744*042d53a7SEvalZero adv_fields.svc_data_uuid128_len = svc_data_uuid128_len;
1745*042d53a7SEvalZero } else if (rc != ENOENT) {
1746*042d53a7SEvalZero console_printf("invalid 'service_data_uuid128' parameter\n");
1747*042d53a7SEvalZero return rc;
1748*042d53a7SEvalZero }
1749*042d53a7SEvalZero
1750*042d53a7SEvalZero rc = parse_arg_byte_stream("uri", CMD_ADV_DATA_URI_MAX_LEN, uri, &uri_len);
1751*042d53a7SEvalZero if (rc == 0) {
1752*042d53a7SEvalZero adv_fields.uri = uri;
1753*042d53a7SEvalZero adv_fields.uri_len = uri_len;
1754*042d53a7SEvalZero } else if (rc != ENOENT) {
1755*042d53a7SEvalZero console_printf("invalid 'uri' parameter\n");
1756*042d53a7SEvalZero return rc;
1757*042d53a7SEvalZero }
1758*042d53a7SEvalZero
1759*042d53a7SEvalZero rc = parse_arg_byte_stream("mfg_data", CMD_ADV_DATA_MFG_DATA_MAX_LEN,
1760*042d53a7SEvalZero mfg_data, &mfg_data_len);
1761*042d53a7SEvalZero if (rc == 0) {
1762*042d53a7SEvalZero adv_fields.mfg_data = mfg_data;
1763*042d53a7SEvalZero adv_fields.mfg_data_len = mfg_data_len;
1764*042d53a7SEvalZero } else if (rc != ENOENT) {
1765*042d53a7SEvalZero console_printf("invalid 'mfg_data' parameter\n");
1766*042d53a7SEvalZero return rc;
1767*042d53a7SEvalZero }
1768*042d53a7SEvalZero
1769*042d53a7SEvalZero tmp = parse_arg_long_bounds("eddystone_measured_power", -100, 20, &rc);
1770*042d53a7SEvalZero if (rc == 0) {
1771*042d53a7SEvalZero eddystone_measured_power = tmp;
1772*042d53a7SEvalZero } else if (rc != ENOENT) {
1773*042d53a7SEvalZero console_printf("invalid 'eddystone_measured_power' parameter\n");
1774*042d53a7SEvalZero return rc;
1775*042d53a7SEvalZero }
1776*042d53a7SEvalZero
1777*042d53a7SEvalZero eddystone_url_full = parse_arg_extract("eddystone_url");
1778*042d53a7SEvalZero if (eddystone_url_full != NULL) {
1779*042d53a7SEvalZero rc = parse_eddystone_url(eddystone_url_full, &eddystone_url_scheme,
1780*042d53a7SEvalZero eddystone_url_body,
1781*042d53a7SEvalZero &eddystone_url_body_len,
1782*042d53a7SEvalZero &eddystone_url_suffix);
1783*042d53a7SEvalZero if (rc != 0) {
1784*042d53a7SEvalZero goto done;
1785*042d53a7SEvalZero }
1786*042d53a7SEvalZero
1787*042d53a7SEvalZero rc = ble_eddystone_set_adv_data_url(&adv_fields, eddystone_url_scheme,
1788*042d53a7SEvalZero eddystone_url_body,
1789*042d53a7SEvalZero eddystone_url_body_len,
1790*042d53a7SEvalZero eddystone_url_suffix,
1791*042d53a7SEvalZero eddystone_measured_power);
1792*042d53a7SEvalZero } else {
1793*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
1794*042d53a7SEvalZero /* Default to legacy PDUs size, mbuf chain will be increased if needed
1795*042d53a7SEvalZero */
1796*042d53a7SEvalZero adv_data = os_msys_get_pkthdr(BLE_HCI_MAX_ADV_DATA_LEN, 0);
1797*042d53a7SEvalZero if (!adv_data) {
1798*042d53a7SEvalZero rc = ENOMEM;
1799*042d53a7SEvalZero goto done;
1800*042d53a7SEvalZero }
1801*042d53a7SEvalZero
1802*042d53a7SEvalZero rc = ble_hs_adv_set_fields_mbuf(&adv_fields, adv_data);
1803*042d53a7SEvalZero if (rc) {
1804*042d53a7SEvalZero goto done;
1805*042d53a7SEvalZero }
1806*042d53a7SEvalZero
1807*042d53a7SEvalZero /* Append some extra data, if requested */
1808*042d53a7SEvalZero extra_data_len = parse_arg_uint16("extra_data_len", &rc);
1809*042d53a7SEvalZero if (rc == 0) {
1810*042d53a7SEvalZero counter = 0;
1811*042d53a7SEvalZero extra_data_len = min(extra_data_len, 1650);
1812*042d53a7SEvalZero while (counter < extra_data_len) {
1813*042d53a7SEvalZero update_pattern(extra_data, counter);
1814*042d53a7SEvalZero
1815*042d53a7SEvalZero os_mbuf_append(adv_data, extra_data,
1816*042d53a7SEvalZero min(extra_data_len - counter, 10));
1817*042d53a7SEvalZero
1818*042d53a7SEvalZero counter += 10;
1819*042d53a7SEvalZero }
1820*042d53a7SEvalZero }
1821*042d53a7SEvalZero
1822*042d53a7SEvalZero if (scan_rsp) {
1823*042d53a7SEvalZero rc = ble_gap_ext_adv_rsp_set_data(instance, adv_data);
1824*042d53a7SEvalZero } else {
1825*042d53a7SEvalZero rc = ble_gap_ext_adv_set_data(instance, adv_data);
1826*042d53a7SEvalZero }
1827*042d53a7SEvalZero #else
1828*042d53a7SEvalZero if (scan_rsp) {
1829*042d53a7SEvalZero rc = ble_gap_adv_rsp_set_fields(&adv_fields);
1830*042d53a7SEvalZero } else {
1831*042d53a7SEvalZero rc = ble_gap_adv_set_fields(&adv_fields);
1832*042d53a7SEvalZero }
1833*042d53a7SEvalZero #endif
1834*042d53a7SEvalZero }
1835*042d53a7SEvalZero done:
1836*042d53a7SEvalZero if (rc != 0) {
1837*042d53a7SEvalZero console_printf("error setting advertisement data; rc=%d\n", rc);
1838*042d53a7SEvalZero return rc;
1839*042d53a7SEvalZero }
1840*042d53a7SEvalZero
1841*042d53a7SEvalZero return 0;
1842*042d53a7SEvalZero }
1843*042d53a7SEvalZero
1844*042d53a7SEvalZero static int
cmd_set_adv_data(int argc,char ** argv)1845*042d53a7SEvalZero cmd_set_adv_data(int argc, char **argv)
1846*042d53a7SEvalZero {
1847*042d53a7SEvalZero return cmd_set_adv_data_or_scan_rsp(argc, argv, false);
1848*042d53a7SEvalZero }
1849*042d53a7SEvalZero
1850*042d53a7SEvalZero static int
cmd_set_scan_rsp(int argc,char ** argv)1851*042d53a7SEvalZero cmd_set_scan_rsp(int argc, char **argv)
1852*042d53a7SEvalZero {
1853*042d53a7SEvalZero return cmd_set_adv_data_or_scan_rsp(argc, argv, true);
1854*042d53a7SEvalZero }
1855*042d53a7SEvalZero
1856*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1857*042d53a7SEvalZero static const struct shell_param set_adv_data_params[] = {
1858*042d53a7SEvalZero {"instance", "default: 0"},
1859*042d53a7SEvalZero {"flags", "usage: =[0-UINT8_MAX]"},
1860*042d53a7SEvalZero {"uuid16", "usage: =[UINT16]"},
1861*042d53a7SEvalZero {"uuid16_is_complete", "usage: =[0-1], default=0"},
1862*042d53a7SEvalZero {"uuid32", "usage: =[UINT32]"},
1863*042d53a7SEvalZero {"uuid32_is_complete", "usage: =[0-1], default=0"},
1864*042d53a7SEvalZero {"uuid128", "usage: =[XX:XX...], len=16 octets"},
1865*042d53a7SEvalZero {"uuid128_is_complete", "usage: =[0-1], default=0"},
1866*042d53a7SEvalZero {"tx_power_level", "usage: =[INT8_MIN-INT8_MAX]"},
1867*042d53a7SEvalZero {"slave_interval_range", "usage: =[XX:XX:XX:XX]"},
1868*042d53a7SEvalZero {"public_target_address", "usage: =[XX:XX:XX:XX:XX:XX]"},
1869*042d53a7SEvalZero {"appearance", "usage: =[UINT16]"},
1870*042d53a7SEvalZero {"name", "usage: =[string]"},
1871*042d53a7SEvalZero {"advertising_interval", "usage: =[UINT16]"},
1872*042d53a7SEvalZero {"service_data_uuid16", "usage: =[XX:XX...]"},
1873*042d53a7SEvalZero {"service_data_uuid32", "usage: =[XX:XX...]"},
1874*042d53a7SEvalZero {"service_data_uuid128", "usage: =[XX:XX...]"},
1875*042d53a7SEvalZero {"uri", "usage: =[XX:XX...]"},
1876*042d53a7SEvalZero {"mfg_data", "usage: =[XX:XX...]"},
1877*042d53a7SEvalZero {"measured_power", "usage: =[-100-20]"},
1878*042d53a7SEvalZero {"eddystone_url", "usage: =[string]"},
1879*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
1880*042d53a7SEvalZero {"extra_data_len", "usage: =[UINT16]"},
1881*042d53a7SEvalZero #endif
1882*042d53a7SEvalZero {NULL, NULL}
1883*042d53a7SEvalZero };
1884*042d53a7SEvalZero
1885*042d53a7SEvalZero static const struct shell_cmd_help set_adv_data_help = {
1886*042d53a7SEvalZero .summary = "set advertising data",
1887*042d53a7SEvalZero .usage = NULL,
1888*042d53a7SEvalZero .params = set_adv_data_params,
1889*042d53a7SEvalZero };
1890*042d53a7SEvalZero
1891*042d53a7SEvalZero static const struct shell_cmd_help set_scan_rsp_help = {
1892*042d53a7SEvalZero .summary = "set scan response",
1893*042d53a7SEvalZero .usage = NULL,
1894*042d53a7SEvalZero .params = set_adv_data_params,
1895*042d53a7SEvalZero };
1896*042d53a7SEvalZero #endif
1897*042d53a7SEvalZero
1898*042d53a7SEvalZero /*****************************************************************************
1899*042d53a7SEvalZero * $set-priv-mode *
1900*042d53a7SEvalZero *****************************************************************************/
1901*042d53a7SEvalZero
1902*042d53a7SEvalZero static int
cmd_set_priv_mode(int argc,char ** argv)1903*042d53a7SEvalZero cmd_set_priv_mode(int argc, char **argv)
1904*042d53a7SEvalZero {
1905*042d53a7SEvalZero ble_addr_t addr;
1906*042d53a7SEvalZero uint8_t priv_mode;
1907*042d53a7SEvalZero int rc;
1908*042d53a7SEvalZero
1909*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1910*042d53a7SEvalZero if (rc != 0) {
1911*042d53a7SEvalZero return rc;
1912*042d53a7SEvalZero }
1913*042d53a7SEvalZero
1914*042d53a7SEvalZero addr.type = parse_arg_kv_dflt("addr_type", cmd_set_addr_types,
1915*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
1916*042d53a7SEvalZero if (rc != 0) {
1917*042d53a7SEvalZero console_printf("invalid 'addr_type' parameter\n");
1918*042d53a7SEvalZero return rc;
1919*042d53a7SEvalZero }
1920*042d53a7SEvalZero
1921*042d53a7SEvalZero rc = parse_arg_mac("addr", addr.val);
1922*042d53a7SEvalZero if (rc != 0) {
1923*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
1924*042d53a7SEvalZero return rc;
1925*042d53a7SEvalZero }
1926*042d53a7SEvalZero
1927*042d53a7SEvalZero priv_mode = parse_arg_uint8("mode", &rc);
1928*042d53a7SEvalZero if (rc != 0) {
1929*042d53a7SEvalZero console_printf("missing mode\n");
1930*042d53a7SEvalZero return rc;
1931*042d53a7SEvalZero }
1932*042d53a7SEvalZero
1933*042d53a7SEvalZero return ble_gap_set_priv_mode(&addr, priv_mode);
1934*042d53a7SEvalZero }
1935*042d53a7SEvalZero
1936*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
1937*042d53a7SEvalZero static const struct shell_param set_priv_mode_params[] = {
1938*042d53a7SEvalZero {"addr", "set priv mode for device address, usage: =[XX:XX:XX:XX:XX:XX]"},
1939*042d53a7SEvalZero {"addr_type", "set priv mode for device address type, usage: =[public|random], default: public"},
1940*042d53a7SEvalZero {"mode", "set priv mode, usage: =[0-UINT8_MAX]"},
1941*042d53a7SEvalZero {NULL, NULL}
1942*042d53a7SEvalZero };
1943*042d53a7SEvalZero
1944*042d53a7SEvalZero static const struct shell_cmd_help set_priv_mode_help = {
1945*042d53a7SEvalZero .summary = "set priv mode",
1946*042d53a7SEvalZero .usage = NULL,
1947*042d53a7SEvalZero .params = set_priv_mode_params,
1948*042d53a7SEvalZero };
1949*042d53a7SEvalZero #endif
1950*042d53a7SEvalZero
1951*042d53a7SEvalZero /*****************************************************************************
1952*042d53a7SEvalZero * $white-list *
1953*042d53a7SEvalZero *****************************************************************************/
1954*042d53a7SEvalZero
1955*042d53a7SEvalZero #define CMD_WL_MAX_SZ 8
1956*042d53a7SEvalZero
1957*042d53a7SEvalZero static int
cmd_white_list(int argc,char ** argv)1958*042d53a7SEvalZero cmd_white_list(int argc, char **argv)
1959*042d53a7SEvalZero {
1960*042d53a7SEvalZero static ble_addr_t addrs[CMD_WL_MAX_SZ];
1961*042d53a7SEvalZero int addrs_cnt;
1962*042d53a7SEvalZero int rc;
1963*042d53a7SEvalZero
1964*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
1965*042d53a7SEvalZero if (rc != 0) {
1966*042d53a7SEvalZero return rc;
1967*042d53a7SEvalZero }
1968*042d53a7SEvalZero
1969*042d53a7SEvalZero addrs_cnt = 0;
1970*042d53a7SEvalZero while (1) {
1971*042d53a7SEvalZero if (addrs_cnt >= CMD_WL_MAX_SZ) {
1972*042d53a7SEvalZero return EINVAL;
1973*042d53a7SEvalZero }
1974*042d53a7SEvalZero
1975*042d53a7SEvalZero rc = parse_arg_mac("addr", addrs[addrs_cnt].val);
1976*042d53a7SEvalZero if (rc == ENOENT) {
1977*042d53a7SEvalZero break;
1978*042d53a7SEvalZero } else if (rc != 0) {
1979*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
1980*042d53a7SEvalZero return rc;
1981*042d53a7SEvalZero }
1982*042d53a7SEvalZero
1983*042d53a7SEvalZero addrs[addrs_cnt].type = parse_arg_kv("addr_type", cmd_addr_type, &rc);
1984*042d53a7SEvalZero if (rc != 0) {
1985*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
1986*042d53a7SEvalZero return rc;
1987*042d53a7SEvalZero }
1988*042d53a7SEvalZero
1989*042d53a7SEvalZero addrs_cnt++;
1990*042d53a7SEvalZero }
1991*042d53a7SEvalZero
1992*042d53a7SEvalZero if (addrs_cnt == 0) {
1993*042d53a7SEvalZero return EINVAL;
1994*042d53a7SEvalZero }
1995*042d53a7SEvalZero
1996*042d53a7SEvalZero btshell_wl_set(addrs, addrs_cnt);
1997*042d53a7SEvalZero
1998*042d53a7SEvalZero return 0;
1999*042d53a7SEvalZero }
2000*042d53a7SEvalZero
2001*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2002*042d53a7SEvalZero static const struct shell_param white_list_params[] = {
2003*042d53a7SEvalZero {"addr", "white-list device addresses, usage: =[XX:XX:XX:XX:XX:XX]"},
2004*042d53a7SEvalZero {"addr_type", "white-list address types, usage: =[public|random]"},
2005*042d53a7SEvalZero {NULL, NULL}
2006*042d53a7SEvalZero };
2007*042d53a7SEvalZero
2008*042d53a7SEvalZero static const struct shell_cmd_help white_list_help = {
2009*042d53a7SEvalZero .summary = "set white-list addresses",
2010*042d53a7SEvalZero .usage = NULL,
2011*042d53a7SEvalZero .params = white_list_params,
2012*042d53a7SEvalZero };
2013*042d53a7SEvalZero #endif
2014*042d53a7SEvalZero
2015*042d53a7SEvalZero /*****************************************************************************
2016*042d53a7SEvalZero * $conn-rssi *
2017*042d53a7SEvalZero *****************************************************************************/
2018*042d53a7SEvalZero
2019*042d53a7SEvalZero static int
cmd_conn_rssi(int argc,char ** argv)2020*042d53a7SEvalZero cmd_conn_rssi(int argc, char **argv)
2021*042d53a7SEvalZero {
2022*042d53a7SEvalZero uint16_t conn_handle;
2023*042d53a7SEvalZero int8_t rssi;
2024*042d53a7SEvalZero int rc;
2025*042d53a7SEvalZero
2026*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2027*042d53a7SEvalZero if (rc != 0) {
2028*042d53a7SEvalZero return rc;
2029*042d53a7SEvalZero }
2030*042d53a7SEvalZero
2031*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2032*042d53a7SEvalZero if (rc != 0) {
2033*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2034*042d53a7SEvalZero return rc;
2035*042d53a7SEvalZero }
2036*042d53a7SEvalZero
2037*042d53a7SEvalZero rc = btshell_rssi(conn_handle, &rssi);
2038*042d53a7SEvalZero if (rc != 0) {
2039*042d53a7SEvalZero console_printf("error reading rssi; rc=%d\n", rc);
2040*042d53a7SEvalZero return rc;
2041*042d53a7SEvalZero }
2042*042d53a7SEvalZero
2043*042d53a7SEvalZero console_printf("conn=%d rssi=%d\n", conn_handle, rssi);
2044*042d53a7SEvalZero
2045*042d53a7SEvalZero return 0;
2046*042d53a7SEvalZero }
2047*042d53a7SEvalZero
2048*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2049*042d53a7SEvalZero static const struct shell_param conn_rssi_params[] = {
2050*042d53a7SEvalZero {"conn", "connection handle parameter, usage: =<UINT16>"},
2051*042d53a7SEvalZero {NULL, NULL}
2052*042d53a7SEvalZero };
2053*042d53a7SEvalZero
2054*042d53a7SEvalZero static const struct shell_cmd_help conn_rssi_help = {
2055*042d53a7SEvalZero .summary = "check connection rssi",
2056*042d53a7SEvalZero .usage = NULL,
2057*042d53a7SEvalZero .params = conn_rssi_params,
2058*042d53a7SEvalZero };
2059*042d53a7SEvalZero #endif
2060*042d53a7SEvalZero
2061*042d53a7SEvalZero /*****************************************************************************
2062*042d53a7SEvalZero * $conn-update-params *
2063*042d53a7SEvalZero *****************************************************************************/
2064*042d53a7SEvalZero
2065*042d53a7SEvalZero static int
cmd_conn_update_params(int argc,char ** argv)2066*042d53a7SEvalZero cmd_conn_update_params(int argc, char **argv)
2067*042d53a7SEvalZero {
2068*042d53a7SEvalZero struct ble_gap_upd_params params;
2069*042d53a7SEvalZero uint16_t conn_handle;
2070*042d53a7SEvalZero int rc;
2071*042d53a7SEvalZero
2072*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2073*042d53a7SEvalZero if (rc != 0) {
2074*042d53a7SEvalZero return rc;
2075*042d53a7SEvalZero }
2076*042d53a7SEvalZero
2077*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2078*042d53a7SEvalZero if (rc != 0) {
2079*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2080*042d53a7SEvalZero return rc;
2081*042d53a7SEvalZero }
2082*042d53a7SEvalZero
2083*042d53a7SEvalZero params.itvl_min = parse_arg_uint16_dflt("interval_min",
2084*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MIN,
2085*042d53a7SEvalZero &rc);
2086*042d53a7SEvalZero if (rc != 0) {
2087*042d53a7SEvalZero console_printf("invalid 'interval_min' parameter\n");
2088*042d53a7SEvalZero return rc;
2089*042d53a7SEvalZero }
2090*042d53a7SEvalZero
2091*042d53a7SEvalZero params.itvl_max = parse_arg_uint16_dflt("interval_max",
2092*042d53a7SEvalZero BLE_GAP_INITIAL_CONN_ITVL_MAX,
2093*042d53a7SEvalZero &rc);
2094*042d53a7SEvalZero if (rc != 0) {
2095*042d53a7SEvalZero console_printf("invalid 'interval_max' parameter\n");
2096*042d53a7SEvalZero return rc;
2097*042d53a7SEvalZero }
2098*042d53a7SEvalZero
2099*042d53a7SEvalZero params.latency = parse_arg_uint16_dflt("latency", 0, &rc);
2100*042d53a7SEvalZero if (rc != 0) {
2101*042d53a7SEvalZero console_printf("invalid 'latency' parameter\n");
2102*042d53a7SEvalZero return rc;
2103*042d53a7SEvalZero }
2104*042d53a7SEvalZero
2105*042d53a7SEvalZero params.supervision_timeout = parse_arg_uint16_dflt("timeout", 0x0100, &rc);
2106*042d53a7SEvalZero if (rc != 0) {
2107*042d53a7SEvalZero console_printf("invalid 'timeout' parameter\n");
2108*042d53a7SEvalZero return rc;
2109*042d53a7SEvalZero }
2110*042d53a7SEvalZero
2111*042d53a7SEvalZero params.min_ce_len = parse_arg_uint16_dflt("min_conn_event_len",
2112*042d53a7SEvalZero 0x0010, &rc);
2113*042d53a7SEvalZero if (rc != 0) {
2114*042d53a7SEvalZero console_printf("invalid 'min_conn_event_len' parameter\n");
2115*042d53a7SEvalZero return rc;
2116*042d53a7SEvalZero }
2117*042d53a7SEvalZero
2118*042d53a7SEvalZero params.max_ce_len = parse_arg_uint16_dflt("max_conn_event_len",
2119*042d53a7SEvalZero 0x0300, &rc);
2120*042d53a7SEvalZero if (rc != 0) {
2121*042d53a7SEvalZero console_printf("invalid 'max_conn_event_len' parameter\n");
2122*042d53a7SEvalZero return rc;
2123*042d53a7SEvalZero }
2124*042d53a7SEvalZero
2125*042d53a7SEvalZero rc = btshell_update_conn(conn_handle, ¶ms);
2126*042d53a7SEvalZero if (rc != 0) {
2127*042d53a7SEvalZero console_printf("error updating connection; rc=%d\n", rc);
2128*042d53a7SEvalZero return rc;
2129*042d53a7SEvalZero }
2130*042d53a7SEvalZero
2131*042d53a7SEvalZero return 0;
2132*042d53a7SEvalZero }
2133*042d53a7SEvalZero
2134*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2135*042d53a7SEvalZero static const struct shell_param conn_update_params_params[] = {
2136*042d53a7SEvalZero {"conn", "conn_update_paramsion handle, usage: =<UINT16>"},
2137*042d53a7SEvalZero {"interval_min", "usage: =[0-UINT16_MAX], default: 30"},
2138*042d53a7SEvalZero {"interval_max", "usage: =[0-UINT16_MAX], default: 50"},
2139*042d53a7SEvalZero {"latency", "usage: =[UINT16], default: 0"},
2140*042d53a7SEvalZero {"timeout", "usage: =[UINT16], default: 0x0100"},
2141*042d53a7SEvalZero {"min_conn_event_len", "usage: =[UINT16], default: 0x0010"},
2142*042d53a7SEvalZero {"max_conn_event_len", "usage: =[UINT16], default: 0x0300"},
2143*042d53a7SEvalZero {NULL, NULL}
2144*042d53a7SEvalZero };
2145*042d53a7SEvalZero
2146*042d53a7SEvalZero static const struct shell_cmd_help conn_update_params_help = {
2147*042d53a7SEvalZero .summary = "update connection parameters",
2148*042d53a7SEvalZero .usage = "conn_update_params usage",
2149*042d53a7SEvalZero .params = conn_update_params_params,
2150*042d53a7SEvalZero };
2151*042d53a7SEvalZero #endif
2152*042d53a7SEvalZero
2153*042d53a7SEvalZero /*****************************************************************************
2154*042d53a7SEvalZero * $conn-datalen *
2155*042d53a7SEvalZero *****************************************************************************/
2156*042d53a7SEvalZero
2157*042d53a7SEvalZero static int
cmd_conn_datalen(int argc,char ** argv)2158*042d53a7SEvalZero cmd_conn_datalen(int argc, char **argv)
2159*042d53a7SEvalZero {
2160*042d53a7SEvalZero uint16_t conn_handle;
2161*042d53a7SEvalZero uint16_t tx_octets;
2162*042d53a7SEvalZero uint16_t tx_time;
2163*042d53a7SEvalZero int rc;
2164*042d53a7SEvalZero
2165*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2166*042d53a7SEvalZero if (rc != 0) {
2167*042d53a7SEvalZero return rc;
2168*042d53a7SEvalZero }
2169*042d53a7SEvalZero
2170*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2171*042d53a7SEvalZero if (rc != 0) {
2172*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2173*042d53a7SEvalZero return rc;
2174*042d53a7SEvalZero }
2175*042d53a7SEvalZero
2176*042d53a7SEvalZero tx_octets = parse_arg_uint16("octets", &rc);
2177*042d53a7SEvalZero if (rc != 0) {
2178*042d53a7SEvalZero console_printf("invalid 'octets' parameter\n");
2179*042d53a7SEvalZero return rc;
2180*042d53a7SEvalZero }
2181*042d53a7SEvalZero
2182*042d53a7SEvalZero tx_time = parse_arg_uint16("time", &rc);
2183*042d53a7SEvalZero if (rc != 0) {
2184*042d53a7SEvalZero console_printf("invalid 'time' parameter\n");
2185*042d53a7SEvalZero return rc;
2186*042d53a7SEvalZero }
2187*042d53a7SEvalZero
2188*042d53a7SEvalZero rc = btshell_datalen(conn_handle, tx_octets, tx_time);
2189*042d53a7SEvalZero if (rc != 0) {
2190*042d53a7SEvalZero console_printf("error setting data length; rc=%d\n", rc);
2191*042d53a7SEvalZero return rc;
2192*042d53a7SEvalZero }
2193*042d53a7SEvalZero
2194*042d53a7SEvalZero return 0;
2195*042d53a7SEvalZero }
2196*042d53a7SEvalZero
2197*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2198*042d53a7SEvalZero static const struct shell_param conn_datalen_params[] = {
2199*042d53a7SEvalZero {"conn", "conn_datalen handle, usage: =<UINT16>"},
2200*042d53a7SEvalZero {"octets", "usage: =<UINT16>"},
2201*042d53a7SEvalZero {"time", "usage: =<UINT16>"},
2202*042d53a7SEvalZero {NULL, NULL}
2203*042d53a7SEvalZero };
2204*042d53a7SEvalZero
2205*042d53a7SEvalZero static const struct shell_cmd_help conn_datalen_help = {
2206*042d53a7SEvalZero .summary = "set data length parameters for connection",
2207*042d53a7SEvalZero .usage = NULL,
2208*042d53a7SEvalZero .params = conn_datalen_params,
2209*042d53a7SEvalZero };
2210*042d53a7SEvalZero #endif
2211*042d53a7SEvalZero
2212*042d53a7SEvalZero /*****************************************************************************
2213*042d53a7SEvalZero * keystore *
2214*042d53a7SEvalZero *****************************************************************************/
2215*042d53a7SEvalZero
2216*042d53a7SEvalZero static const struct kv_pair cmd_keystore_entry_type[] = {
2217*042d53a7SEvalZero { "msec", BLE_STORE_OBJ_TYPE_PEER_SEC },
2218*042d53a7SEvalZero { "ssec", BLE_STORE_OBJ_TYPE_OUR_SEC },
2219*042d53a7SEvalZero { "cccd", BLE_STORE_OBJ_TYPE_CCCD },
2220*042d53a7SEvalZero { NULL }
2221*042d53a7SEvalZero };
2222*042d53a7SEvalZero
2223*042d53a7SEvalZero static int
cmd_keystore_parse_keydata(int argc,char ** argv,union ble_store_key * out,int * obj_type)2224*042d53a7SEvalZero cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out,
2225*042d53a7SEvalZero int *obj_type)
2226*042d53a7SEvalZero {
2227*042d53a7SEvalZero int rc;
2228*042d53a7SEvalZero
2229*042d53a7SEvalZero memset(out, 0, sizeof(*out));
2230*042d53a7SEvalZero *obj_type = parse_arg_kv("type", cmd_keystore_entry_type, &rc);
2231*042d53a7SEvalZero if (rc != 0) {
2232*042d53a7SEvalZero console_printf("invalid 'type' parameter\n");
2233*042d53a7SEvalZero return rc;
2234*042d53a7SEvalZero }
2235*042d53a7SEvalZero
2236*042d53a7SEvalZero switch (*obj_type) {
2237*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_PEER_SEC:
2238*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_OUR_SEC:
2239*042d53a7SEvalZero out->sec.peer_addr.type = parse_arg_kv("addr_type",
2240*042d53a7SEvalZero cmd_addr_type, &rc);
2241*042d53a7SEvalZero if (rc != 0) {
2242*042d53a7SEvalZero console_printf("invalid 'addr_type' parameter\n");
2243*042d53a7SEvalZero return rc;
2244*042d53a7SEvalZero }
2245*042d53a7SEvalZero
2246*042d53a7SEvalZero rc = parse_arg_mac("addr", out->sec.peer_addr.val);
2247*042d53a7SEvalZero if (rc != 0) {
2248*042d53a7SEvalZero console_printf("invalid 'addr' parameter\n");
2249*042d53a7SEvalZero return rc;
2250*042d53a7SEvalZero }
2251*042d53a7SEvalZero
2252*042d53a7SEvalZero out->sec.ediv = parse_arg_uint16("ediv", &rc);
2253*042d53a7SEvalZero if (rc != 0) {
2254*042d53a7SEvalZero console_printf("invalid 'ediv' parameter\n");
2255*042d53a7SEvalZero return rc;
2256*042d53a7SEvalZero }
2257*042d53a7SEvalZero
2258*042d53a7SEvalZero out->sec.rand_num = parse_arg_uint64("rand", &rc);
2259*042d53a7SEvalZero if (rc != 0) {
2260*042d53a7SEvalZero console_printf("invalid 'rand' parameter\n");
2261*042d53a7SEvalZero return rc;
2262*042d53a7SEvalZero }
2263*042d53a7SEvalZero return 0;
2264*042d53a7SEvalZero
2265*042d53a7SEvalZero default:
2266*042d53a7SEvalZero return EINVAL;
2267*042d53a7SEvalZero }
2268*042d53a7SEvalZero }
2269*042d53a7SEvalZero
2270*042d53a7SEvalZero static int
cmd_keystore_parse_valuedata(int argc,char ** argv,int obj_type,union ble_store_key * key,union ble_store_value * out)2271*042d53a7SEvalZero cmd_keystore_parse_valuedata(int argc, char **argv,
2272*042d53a7SEvalZero int obj_type,
2273*042d53a7SEvalZero union ble_store_key *key,
2274*042d53a7SEvalZero union ble_store_value *out)
2275*042d53a7SEvalZero {
2276*042d53a7SEvalZero int rc;
2277*042d53a7SEvalZero int valcnt = 0;
2278*042d53a7SEvalZero memset(out, 0, sizeof(*out));
2279*042d53a7SEvalZero
2280*042d53a7SEvalZero switch (obj_type) {
2281*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_PEER_SEC:
2282*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_OUR_SEC:
2283*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("ltk", out->sec.ltk, 16);
2284*042d53a7SEvalZero if (rc == 0) {
2285*042d53a7SEvalZero out->sec.ltk_present = 1;
2286*042d53a7SEvalZero swap_in_place(out->sec.ltk, 16);
2287*042d53a7SEvalZero valcnt++;
2288*042d53a7SEvalZero } else if (rc != ENOENT) {
2289*042d53a7SEvalZero console_printf("invalid 'ltk' parameter\n");
2290*042d53a7SEvalZero return rc;
2291*042d53a7SEvalZero }
2292*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("irk", out->sec.irk, 16);
2293*042d53a7SEvalZero if (rc == 0) {
2294*042d53a7SEvalZero out->sec.irk_present = 1;
2295*042d53a7SEvalZero swap_in_place(out->sec.irk, 16);
2296*042d53a7SEvalZero valcnt++;
2297*042d53a7SEvalZero } else if (rc != ENOENT) {
2298*042d53a7SEvalZero console_printf("invalid 'irk' parameter\n");
2299*042d53a7SEvalZero return rc;
2300*042d53a7SEvalZero }
2301*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("csrk", out->sec.csrk, 16);
2302*042d53a7SEvalZero if (rc == 0) {
2303*042d53a7SEvalZero out->sec.csrk_present = 1;
2304*042d53a7SEvalZero swap_in_place(out->sec.csrk, 16);
2305*042d53a7SEvalZero valcnt++;
2306*042d53a7SEvalZero } else if (rc != ENOENT) {
2307*042d53a7SEvalZero console_printf("invalid 'csrk' parameter\n");
2308*042d53a7SEvalZero return rc;
2309*042d53a7SEvalZero }
2310*042d53a7SEvalZero out->sec.peer_addr = key->sec.peer_addr;
2311*042d53a7SEvalZero out->sec.ediv = key->sec.ediv;
2312*042d53a7SEvalZero out->sec.rand_num = key->sec.rand_num;
2313*042d53a7SEvalZero break;
2314*042d53a7SEvalZero }
2315*042d53a7SEvalZero
2316*042d53a7SEvalZero if (valcnt) {
2317*042d53a7SEvalZero return 0;
2318*042d53a7SEvalZero }
2319*042d53a7SEvalZero return -1;
2320*042d53a7SEvalZero }
2321*042d53a7SEvalZero
2322*042d53a7SEvalZero /*****************************************************************************
2323*042d53a7SEvalZero * keystore-add *
2324*042d53a7SEvalZero *****************************************************************************/
2325*042d53a7SEvalZero
2326*042d53a7SEvalZero static int
cmd_keystore_add(int argc,char ** argv)2327*042d53a7SEvalZero cmd_keystore_add(int argc, char **argv)
2328*042d53a7SEvalZero {
2329*042d53a7SEvalZero union ble_store_key key;
2330*042d53a7SEvalZero union ble_store_value value;
2331*042d53a7SEvalZero int obj_type;
2332*042d53a7SEvalZero int rc;
2333*042d53a7SEvalZero
2334*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2335*042d53a7SEvalZero if (rc != 0) {
2336*042d53a7SEvalZero return rc;
2337*042d53a7SEvalZero }
2338*042d53a7SEvalZero
2339*042d53a7SEvalZero rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
2340*042d53a7SEvalZero
2341*042d53a7SEvalZero if (rc) {
2342*042d53a7SEvalZero return rc;
2343*042d53a7SEvalZero }
2344*042d53a7SEvalZero
2345*042d53a7SEvalZero rc = cmd_keystore_parse_valuedata(argc, argv, obj_type, &key, &value);
2346*042d53a7SEvalZero
2347*042d53a7SEvalZero if (rc) {
2348*042d53a7SEvalZero return rc;
2349*042d53a7SEvalZero }
2350*042d53a7SEvalZero
2351*042d53a7SEvalZero switch(obj_type) {
2352*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_PEER_SEC:
2353*042d53a7SEvalZero rc = ble_store_write_peer_sec(&value.sec);
2354*042d53a7SEvalZero break;
2355*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_OUR_SEC:
2356*042d53a7SEvalZero rc = ble_store_write_our_sec(&value.sec);
2357*042d53a7SEvalZero break;
2358*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_CCCD:
2359*042d53a7SEvalZero rc = ble_store_write_cccd(&value.cccd);
2360*042d53a7SEvalZero break;
2361*042d53a7SEvalZero default:
2362*042d53a7SEvalZero rc = ble_store_write(obj_type, &value);
2363*042d53a7SEvalZero }
2364*042d53a7SEvalZero return rc;
2365*042d53a7SEvalZero }
2366*042d53a7SEvalZero
2367*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2368*042d53a7SEvalZero static const struct shell_param keystore_add_params[] = {
2369*042d53a7SEvalZero {"type", "entry type, usage: =<msec|ssec|cccd>"},
2370*042d53a7SEvalZero {"addr_type", "usage: =<public|random>"},
2371*042d53a7SEvalZero {"addr", "usage: =<XX:XX:XX:XX:XX:XX>"},
2372*042d53a7SEvalZero {"ediv", "usage: =<UINT16>"},
2373*042d53a7SEvalZero {"rand", "usage: =<UINT64>"},
2374*042d53a7SEvalZero {"ltk", "usage: =<XX:XX:...>, len=16 octets"},
2375*042d53a7SEvalZero {"irk", "usage: =<XX:XX:...>, len=16 octets"},
2376*042d53a7SEvalZero {"csrk", "usage: =<XX:XX:...>, len=16 octets"},
2377*042d53a7SEvalZero {NULL, NULL}
2378*042d53a7SEvalZero };
2379*042d53a7SEvalZero
2380*042d53a7SEvalZero static const struct shell_cmd_help keystore_add_help = {
2381*042d53a7SEvalZero .summary = "add data to keystore",
2382*042d53a7SEvalZero .usage = NULL,
2383*042d53a7SEvalZero .params = keystore_add_params,
2384*042d53a7SEvalZero };
2385*042d53a7SEvalZero #endif
2386*042d53a7SEvalZero
2387*042d53a7SEvalZero /*****************************************************************************
2388*042d53a7SEvalZero * keystore-del *
2389*042d53a7SEvalZero *****************************************************************************/
2390*042d53a7SEvalZero
2391*042d53a7SEvalZero static int
cmd_keystore_del(int argc,char ** argv)2392*042d53a7SEvalZero cmd_keystore_del(int argc, char **argv)
2393*042d53a7SEvalZero {
2394*042d53a7SEvalZero union ble_store_key key;
2395*042d53a7SEvalZero int obj_type;
2396*042d53a7SEvalZero int rc;
2397*042d53a7SEvalZero
2398*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2399*042d53a7SEvalZero if (rc != 0) {
2400*042d53a7SEvalZero return rc;
2401*042d53a7SEvalZero }
2402*042d53a7SEvalZero
2403*042d53a7SEvalZero rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
2404*042d53a7SEvalZero
2405*042d53a7SEvalZero if (rc) {
2406*042d53a7SEvalZero return rc;
2407*042d53a7SEvalZero }
2408*042d53a7SEvalZero rc = ble_store_delete(obj_type, &key);
2409*042d53a7SEvalZero return rc;
2410*042d53a7SEvalZero }
2411*042d53a7SEvalZero
2412*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2413*042d53a7SEvalZero static const struct shell_param keystore_del_params[] = {
2414*042d53a7SEvalZero {"type", "entry type, usage: =<msec|ssec|cccd>"},
2415*042d53a7SEvalZero {"addr_type", "usage: =<public|random>"},
2416*042d53a7SEvalZero {"addr", "usage: =<XX:XX:XX:XX:XX:XX>"},
2417*042d53a7SEvalZero {"ediv", "usage: =<UINT16>"},
2418*042d53a7SEvalZero {"rand", "usage: =<UINT64>"},
2419*042d53a7SEvalZero {NULL, NULL}
2420*042d53a7SEvalZero };
2421*042d53a7SEvalZero
2422*042d53a7SEvalZero static const struct shell_cmd_help keystore_del_help = {
2423*042d53a7SEvalZero .summary = "remove data from keystore",
2424*042d53a7SEvalZero .usage = NULL,
2425*042d53a7SEvalZero .params = keystore_del_params,
2426*042d53a7SEvalZero };
2427*042d53a7SEvalZero #endif
2428*042d53a7SEvalZero
2429*042d53a7SEvalZero /*****************************************************************************
2430*042d53a7SEvalZero * keystore-show *
2431*042d53a7SEvalZero *****************************************************************************/
2432*042d53a7SEvalZero
2433*042d53a7SEvalZero static int
cmd_keystore_iterator(int obj_type,union ble_store_value * val,void * cookie)2434*042d53a7SEvalZero cmd_keystore_iterator(int obj_type,
2435*042d53a7SEvalZero union ble_store_value *val,
2436*042d53a7SEvalZero void *cookie) {
2437*042d53a7SEvalZero
2438*042d53a7SEvalZero switch (obj_type) {
2439*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_PEER_SEC:
2440*042d53a7SEvalZero case BLE_STORE_OBJ_TYPE_OUR_SEC:
2441*042d53a7SEvalZero console_printf("Key: ");
2442*042d53a7SEvalZero if (ble_addr_cmp(&val->sec.peer_addr, BLE_ADDR_ANY) == 0) {
2443*042d53a7SEvalZero console_printf("ediv=%u ", val->sec.ediv);
2444*042d53a7SEvalZero console_printf("ediv=%llu ", val->sec.rand_num);
2445*042d53a7SEvalZero } else {
2446*042d53a7SEvalZero console_printf("addr_type=%u ", val->sec.peer_addr.type);
2447*042d53a7SEvalZero print_addr(val->sec.peer_addr.val);
2448*042d53a7SEvalZero }
2449*042d53a7SEvalZero console_printf("\n");
2450*042d53a7SEvalZero
2451*042d53a7SEvalZero if (val->sec.ltk_present) {
2452*042d53a7SEvalZero console_printf(" LTK: ");
2453*042d53a7SEvalZero print_bytes(val->sec.ltk, 16);
2454*042d53a7SEvalZero console_printf("\n");
2455*042d53a7SEvalZero }
2456*042d53a7SEvalZero if (val->sec.irk_present) {
2457*042d53a7SEvalZero console_printf(" IRK: ");
2458*042d53a7SEvalZero print_bytes(val->sec.irk, 16);
2459*042d53a7SEvalZero console_printf("\n");
2460*042d53a7SEvalZero }
2461*042d53a7SEvalZero if (val->sec.csrk_present) {
2462*042d53a7SEvalZero console_printf(" CSRK: ");
2463*042d53a7SEvalZero print_bytes(val->sec.csrk, 16);
2464*042d53a7SEvalZero console_printf("\n");
2465*042d53a7SEvalZero }
2466*042d53a7SEvalZero break;
2467*042d53a7SEvalZero }
2468*042d53a7SEvalZero return 0;
2469*042d53a7SEvalZero }
2470*042d53a7SEvalZero
2471*042d53a7SEvalZero static int
cmd_keystore_show(int argc,char ** argv)2472*042d53a7SEvalZero cmd_keystore_show(int argc, char **argv)
2473*042d53a7SEvalZero {
2474*042d53a7SEvalZero int type;
2475*042d53a7SEvalZero int rc;
2476*042d53a7SEvalZero
2477*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2478*042d53a7SEvalZero if (rc != 0) {
2479*042d53a7SEvalZero return rc;
2480*042d53a7SEvalZero }
2481*042d53a7SEvalZero
2482*042d53a7SEvalZero type = parse_arg_kv("type", cmd_keystore_entry_type, &rc);
2483*042d53a7SEvalZero if (rc != 0) {
2484*042d53a7SEvalZero console_printf("invalid 'type' parameter\n");
2485*042d53a7SEvalZero return rc;
2486*042d53a7SEvalZero }
2487*042d53a7SEvalZero
2488*042d53a7SEvalZero ble_store_iterate(type, &cmd_keystore_iterator, NULL);
2489*042d53a7SEvalZero return 0;
2490*042d53a7SEvalZero }
2491*042d53a7SEvalZero
2492*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2493*042d53a7SEvalZero static const struct shell_param keystore_show_params[] = {
2494*042d53a7SEvalZero {"type", "entry type, usage: =<msec|ssec|cccd>"},
2495*042d53a7SEvalZero {NULL, NULL}
2496*042d53a7SEvalZero };
2497*042d53a7SEvalZero
2498*042d53a7SEvalZero static const struct shell_cmd_help keystore_show_help = {
2499*042d53a7SEvalZero .summary = "show data in keystore",
2500*042d53a7SEvalZero .usage = NULL,
2501*042d53a7SEvalZero .params = keystore_show_params,
2502*042d53a7SEvalZero };
2503*042d53a7SEvalZero #endif
2504*042d53a7SEvalZero
2505*042d53a7SEvalZero #if NIMBLE_BLE_SM
2506*042d53a7SEvalZero /*****************************************************************************
2507*042d53a7SEvalZero * $auth-passkey *
2508*042d53a7SEvalZero *****************************************************************************/
2509*042d53a7SEvalZero
2510*042d53a7SEvalZero static int
cmd_auth_passkey(int argc,char ** argv)2511*042d53a7SEvalZero cmd_auth_passkey(int argc, char **argv)
2512*042d53a7SEvalZero {
2513*042d53a7SEvalZero uint16_t conn_handle;
2514*042d53a7SEvalZero struct ble_sm_io pk;
2515*042d53a7SEvalZero char *yesno;
2516*042d53a7SEvalZero int rc;
2517*042d53a7SEvalZero
2518*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2519*042d53a7SEvalZero if (rc != 0) {
2520*042d53a7SEvalZero return rc;
2521*042d53a7SEvalZero }
2522*042d53a7SEvalZero
2523*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2524*042d53a7SEvalZero if (rc != 0) {
2525*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2526*042d53a7SEvalZero return rc;
2527*042d53a7SEvalZero }
2528*042d53a7SEvalZero
2529*042d53a7SEvalZero pk.action = parse_arg_uint16("action", &rc);
2530*042d53a7SEvalZero if (rc != 0) {
2531*042d53a7SEvalZero console_printf("invalid 'action' parameter\n");
2532*042d53a7SEvalZero return rc;
2533*042d53a7SEvalZero }
2534*042d53a7SEvalZero
2535*042d53a7SEvalZero switch (pk.action) {
2536*042d53a7SEvalZero case BLE_SM_IOACT_INPUT:
2537*042d53a7SEvalZero case BLE_SM_IOACT_DISP:
2538*042d53a7SEvalZero /* passkey is 6 digit number */
2539*042d53a7SEvalZero pk.passkey = parse_arg_long_bounds("key", 0, 999999, &rc);
2540*042d53a7SEvalZero if (rc != 0) {
2541*042d53a7SEvalZero console_printf("invalid 'key' parameter\n");
2542*042d53a7SEvalZero return rc;
2543*042d53a7SEvalZero }
2544*042d53a7SEvalZero break;
2545*042d53a7SEvalZero
2546*042d53a7SEvalZero case BLE_SM_IOACT_OOB:
2547*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("oob", pk.oob, 16);
2548*042d53a7SEvalZero if (rc != 0) {
2549*042d53a7SEvalZero console_printf("invalid 'oob' parameter\n");
2550*042d53a7SEvalZero return rc;
2551*042d53a7SEvalZero }
2552*042d53a7SEvalZero break;
2553*042d53a7SEvalZero
2554*042d53a7SEvalZero case BLE_SM_IOACT_NUMCMP:
2555*042d53a7SEvalZero yesno = parse_arg_extract("yesno");
2556*042d53a7SEvalZero if (yesno == NULL) {
2557*042d53a7SEvalZero console_printf("invalid 'yesno' parameter\n");
2558*042d53a7SEvalZero return EINVAL;
2559*042d53a7SEvalZero }
2560*042d53a7SEvalZero
2561*042d53a7SEvalZero switch (yesno[0]) {
2562*042d53a7SEvalZero case 'y':
2563*042d53a7SEvalZero case 'Y':
2564*042d53a7SEvalZero pk.numcmp_accept = 1;
2565*042d53a7SEvalZero break;
2566*042d53a7SEvalZero case 'n':
2567*042d53a7SEvalZero case 'N':
2568*042d53a7SEvalZero pk.numcmp_accept = 0;
2569*042d53a7SEvalZero break;
2570*042d53a7SEvalZero
2571*042d53a7SEvalZero default:
2572*042d53a7SEvalZero console_printf("invalid 'yesno' parameter\n");
2573*042d53a7SEvalZero return EINVAL;
2574*042d53a7SEvalZero }
2575*042d53a7SEvalZero break;
2576*042d53a7SEvalZero
2577*042d53a7SEvalZero default:
2578*042d53a7SEvalZero console_printf("invalid passkey action action=%d\n", pk.action);
2579*042d53a7SEvalZero return EINVAL;
2580*042d53a7SEvalZero }
2581*042d53a7SEvalZero
2582*042d53a7SEvalZero rc = ble_sm_inject_io(conn_handle, &pk);
2583*042d53a7SEvalZero if (rc != 0) {
2584*042d53a7SEvalZero console_printf("error providing passkey; rc=%d\n", rc);
2585*042d53a7SEvalZero return rc;
2586*042d53a7SEvalZero }
2587*042d53a7SEvalZero
2588*042d53a7SEvalZero return 0;
2589*042d53a7SEvalZero }
2590*042d53a7SEvalZero
2591*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2592*042d53a7SEvalZero static const struct shell_param auth_passkey_params[] = {
2593*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
2594*042d53a7SEvalZero {"action", "auth action type, usage: =<UINT16>"},
2595*042d53a7SEvalZero {"key", "usage: =[0-999999]"},
2596*042d53a7SEvalZero {"oob", "usage: =[XX:XX...], len=16 octets"},
2597*042d53a7SEvalZero {"yesno", "usage: =[string]"},
2598*042d53a7SEvalZero {NULL, NULL}
2599*042d53a7SEvalZero };
2600*042d53a7SEvalZero
2601*042d53a7SEvalZero static const struct shell_cmd_help auth_passkey_help = {
2602*042d53a7SEvalZero .summary = "set authorization passkey options",
2603*042d53a7SEvalZero .usage = NULL,
2604*042d53a7SEvalZero .params = auth_passkey_params,
2605*042d53a7SEvalZero };
2606*042d53a7SEvalZero #endif
2607*042d53a7SEvalZero
2608*042d53a7SEvalZero /*****************************************************************************
2609*042d53a7SEvalZero * $security-pair *
2610*042d53a7SEvalZero *****************************************************************************/
2611*042d53a7SEvalZero
2612*042d53a7SEvalZero static int
cmd_security_pair(int argc,char ** argv)2613*042d53a7SEvalZero cmd_security_pair(int argc, char **argv)
2614*042d53a7SEvalZero {
2615*042d53a7SEvalZero uint16_t conn_handle;
2616*042d53a7SEvalZero int rc;
2617*042d53a7SEvalZero
2618*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2619*042d53a7SEvalZero if (rc != 0) {
2620*042d53a7SEvalZero return rc;
2621*042d53a7SEvalZero }
2622*042d53a7SEvalZero
2623*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2624*042d53a7SEvalZero if (rc != 0) {
2625*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2626*042d53a7SEvalZero return rc;
2627*042d53a7SEvalZero }
2628*042d53a7SEvalZero
2629*042d53a7SEvalZero rc = btshell_sec_pair(conn_handle);
2630*042d53a7SEvalZero if (rc != 0) {
2631*042d53a7SEvalZero console_printf("error initiating pairing; rc=%d\n", rc);
2632*042d53a7SEvalZero return rc;
2633*042d53a7SEvalZero }
2634*042d53a7SEvalZero
2635*042d53a7SEvalZero return 0;
2636*042d53a7SEvalZero }
2637*042d53a7SEvalZero
2638*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2639*042d53a7SEvalZero static const struct shell_param security_pair_params[] = {
2640*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
2641*042d53a7SEvalZero {NULL, NULL}
2642*042d53a7SEvalZero };
2643*042d53a7SEvalZero
2644*042d53a7SEvalZero static const struct shell_cmd_help security_pair_help = {
2645*042d53a7SEvalZero .summary = "start pairing procedure for connection",
2646*042d53a7SEvalZero .usage = NULL,
2647*042d53a7SEvalZero .params = security_pair_params,
2648*042d53a7SEvalZero };
2649*042d53a7SEvalZero #endif
2650*042d53a7SEvalZero
2651*042d53a7SEvalZero /*****************************************************************************
2652*042d53a7SEvalZero * $security-unpair *
2653*042d53a7SEvalZero *****************************************************************************/
2654*042d53a7SEvalZero
2655*042d53a7SEvalZero static int
cmd_security_unpair(int argc,char ** argv)2656*042d53a7SEvalZero cmd_security_unpair(int argc, char **argv)
2657*042d53a7SEvalZero {
2658*042d53a7SEvalZero ble_addr_t peer;
2659*042d53a7SEvalZero int rc;
2660*042d53a7SEvalZero
2661*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2662*042d53a7SEvalZero if (rc != 0) {
2663*042d53a7SEvalZero return rc;
2664*042d53a7SEvalZero }
2665*042d53a7SEvalZero
2666*042d53a7SEvalZero rc = parse_arg_mac("peer_addr", peer.val);
2667*042d53a7SEvalZero if (rc == 0) {
2668*042d53a7SEvalZero
2669*042d53a7SEvalZero peer.type = parse_arg_kv_dflt("peer_addr_type",
2670*042d53a7SEvalZero cmd_peer_addr_types,
2671*042d53a7SEvalZero BLE_ADDR_PUBLIC, &rc);
2672*042d53a7SEvalZero if (rc != 0) {
2673*042d53a7SEvalZero console_printf("invalid 'peer_addr_type' parameter\n");
2674*042d53a7SEvalZero return rc;
2675*042d53a7SEvalZero }
2676*042d53a7SEvalZero } else {
2677*042d53a7SEvalZero console_printf("invalid 'peer_addr' parameter\n");
2678*042d53a7SEvalZero return rc;
2679*042d53a7SEvalZero }
2680*042d53a7SEvalZero
2681*042d53a7SEvalZero rc = ble_gap_unpair(&peer);
2682*042d53a7SEvalZero if (rc != 0) {
2683*042d53a7SEvalZero console_printf("error unpairing; rc=%d\n", rc);
2684*042d53a7SEvalZero return rc;
2685*042d53a7SEvalZero }
2686*042d53a7SEvalZero
2687*042d53a7SEvalZero return 0;
2688*042d53a7SEvalZero }
2689*042d53a7SEvalZero
2690*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2691*042d53a7SEvalZero static const struct shell_param security_unpair_params[] = {
2692*042d53a7SEvalZero {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
2693*042d53a7SEvalZero {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
2694*042d53a7SEvalZero {NULL, NULL}
2695*042d53a7SEvalZero };
2696*042d53a7SEvalZero
2697*042d53a7SEvalZero static const struct shell_cmd_help security_unpair_help = {
2698*042d53a7SEvalZero .summary = "unpair a peer device",
2699*042d53a7SEvalZero .usage = NULL,
2700*042d53a7SEvalZero .params = security_unpair_params,
2701*042d53a7SEvalZero };
2702*042d53a7SEvalZero #endif
2703*042d53a7SEvalZero
2704*042d53a7SEvalZero /*****************************************************************************
2705*042d53a7SEvalZero * $security-start *
2706*042d53a7SEvalZero *****************************************************************************/
2707*042d53a7SEvalZero
2708*042d53a7SEvalZero static int
cmd_security_start(int argc,char ** argv)2709*042d53a7SEvalZero cmd_security_start(int argc, char **argv)
2710*042d53a7SEvalZero {
2711*042d53a7SEvalZero uint16_t conn_handle;
2712*042d53a7SEvalZero int rc;
2713*042d53a7SEvalZero
2714*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2715*042d53a7SEvalZero if (rc != 0) {
2716*042d53a7SEvalZero return rc;
2717*042d53a7SEvalZero }
2718*042d53a7SEvalZero
2719*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2720*042d53a7SEvalZero if (rc != 0) {
2721*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2722*042d53a7SEvalZero return rc;
2723*042d53a7SEvalZero }
2724*042d53a7SEvalZero
2725*042d53a7SEvalZero rc = btshell_sec_start(conn_handle);
2726*042d53a7SEvalZero if (rc != 0) {
2727*042d53a7SEvalZero console_printf("error starting security; rc=%d\n", rc);
2728*042d53a7SEvalZero return rc;
2729*042d53a7SEvalZero }
2730*042d53a7SEvalZero
2731*042d53a7SEvalZero return 0;
2732*042d53a7SEvalZero }
2733*042d53a7SEvalZero
2734*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2735*042d53a7SEvalZero static const struct shell_param security_start_params[] = {
2736*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
2737*042d53a7SEvalZero {NULL, NULL}
2738*042d53a7SEvalZero };
2739*042d53a7SEvalZero
2740*042d53a7SEvalZero static const struct shell_cmd_help security_start_help = {
2741*042d53a7SEvalZero .summary = "start security procedure for connection",
2742*042d53a7SEvalZero .usage = NULL,
2743*042d53a7SEvalZero .params = security_start_params,
2744*042d53a7SEvalZero };
2745*042d53a7SEvalZero #endif
2746*042d53a7SEvalZero
2747*042d53a7SEvalZero /*****************************************************************************
2748*042d53a7SEvalZero * $security-encryption *
2749*042d53a7SEvalZero *****************************************************************************/
2750*042d53a7SEvalZero
2751*042d53a7SEvalZero static int
cmd_security_encryption(int argc,char ** argv)2752*042d53a7SEvalZero cmd_security_encryption(int argc, char **argv)
2753*042d53a7SEvalZero {
2754*042d53a7SEvalZero uint16_t conn_handle;
2755*042d53a7SEvalZero uint16_t ediv;
2756*042d53a7SEvalZero uint64_t rand_val;
2757*042d53a7SEvalZero uint8_t ltk[16];
2758*042d53a7SEvalZero int rc;
2759*042d53a7SEvalZero int auth;
2760*042d53a7SEvalZero
2761*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2762*042d53a7SEvalZero if (rc != 0) {
2763*042d53a7SEvalZero return rc;
2764*042d53a7SEvalZero }
2765*042d53a7SEvalZero
2766*042d53a7SEvalZero conn_handle = parse_arg_uint16("conn", &rc);
2767*042d53a7SEvalZero if (rc != 0) {
2768*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
2769*042d53a7SEvalZero return rc;
2770*042d53a7SEvalZero }
2771*042d53a7SEvalZero
2772*042d53a7SEvalZero ediv = parse_arg_uint16("ediv", &rc);
2773*042d53a7SEvalZero if (rc == ENOENT) {
2774*042d53a7SEvalZero rc = btshell_sec_restart(conn_handle, NULL, 0, 0, 0);
2775*042d53a7SEvalZero } else {
2776*042d53a7SEvalZero rand_val = parse_arg_uint64("rand", &rc);
2777*042d53a7SEvalZero if (rc != 0) {
2778*042d53a7SEvalZero console_printf("invalid 'rand' parameter\n");
2779*042d53a7SEvalZero return rc;
2780*042d53a7SEvalZero }
2781*042d53a7SEvalZero
2782*042d53a7SEvalZero auth = parse_arg_bool("auth", &rc);
2783*042d53a7SEvalZero if (rc != 0) {
2784*042d53a7SEvalZero console_printf("invalid 'auth' parameter\n");
2785*042d53a7SEvalZero return rc;
2786*042d53a7SEvalZero }
2787*042d53a7SEvalZero
2788*042d53a7SEvalZero rc = parse_arg_byte_stream_exact_length("ltk", ltk, 16);
2789*042d53a7SEvalZero if (rc != 0) {
2790*042d53a7SEvalZero console_printf("invalid 'ltk' parameter\n");
2791*042d53a7SEvalZero return rc;
2792*042d53a7SEvalZero }
2793*042d53a7SEvalZero
2794*042d53a7SEvalZero rc = btshell_sec_restart(conn_handle, ltk, ediv, rand_val, auth);
2795*042d53a7SEvalZero }
2796*042d53a7SEvalZero
2797*042d53a7SEvalZero if (rc != 0) {
2798*042d53a7SEvalZero console_printf("error initiating encryption; rc=%d\n", rc);
2799*042d53a7SEvalZero return rc;
2800*042d53a7SEvalZero }
2801*042d53a7SEvalZero
2802*042d53a7SEvalZero return 0;
2803*042d53a7SEvalZero }
2804*042d53a7SEvalZero
2805*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2806*042d53a7SEvalZero static const struct shell_param security_encryption_params[] = {
2807*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
2808*042d53a7SEvalZero {"ediv", "usage: =[UINT16]"},
2809*042d53a7SEvalZero {"rand", "usage: =[UINT64]"},
2810*042d53a7SEvalZero {"auth", "usage: =[0-1]"},
2811*042d53a7SEvalZero {"ltk", "usage: =[XX:XX...], len=16 octets"},
2812*042d53a7SEvalZero {NULL, NULL}
2813*042d53a7SEvalZero };
2814*042d53a7SEvalZero
2815*042d53a7SEvalZero static const struct shell_cmd_help security_encryption_help = {
2816*042d53a7SEvalZero .summary = "start encryption procedure for connection",
2817*042d53a7SEvalZero .usage = NULL,
2818*042d53a7SEvalZero .params = security_encryption_params,
2819*042d53a7SEvalZero };
2820*042d53a7SEvalZero #endif
2821*042d53a7SEvalZero
2822*042d53a7SEvalZero /*****************************************************************************
2823*042d53a7SEvalZero * $security-set-data *
2824*042d53a7SEvalZero *****************************************************************************/
2825*042d53a7SEvalZero
2826*042d53a7SEvalZero static int
cmd_security_set_data(int argc,char ** argv)2827*042d53a7SEvalZero cmd_security_set_data(int argc, char **argv)
2828*042d53a7SEvalZero {
2829*042d53a7SEvalZero uint8_t tmp;
2830*042d53a7SEvalZero int good;
2831*042d53a7SEvalZero int rc;
2832*042d53a7SEvalZero
2833*042d53a7SEvalZero good = 0;
2834*042d53a7SEvalZero
2835*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2836*042d53a7SEvalZero if (rc != 0) {
2837*042d53a7SEvalZero return rc;
2838*042d53a7SEvalZero }
2839*042d53a7SEvalZero
2840*042d53a7SEvalZero tmp = parse_arg_bool("oob_flag", &rc);
2841*042d53a7SEvalZero if (rc == 0) {
2842*042d53a7SEvalZero ble_hs_cfg.sm_oob_data_flag = tmp;
2843*042d53a7SEvalZero good++;
2844*042d53a7SEvalZero } else if (rc != ENOENT) {
2845*042d53a7SEvalZero console_printf("invalid 'oob_flag' parameter\n");
2846*042d53a7SEvalZero return rc;
2847*042d53a7SEvalZero }
2848*042d53a7SEvalZero
2849*042d53a7SEvalZero tmp = parse_arg_bool("mitm_flag", &rc);
2850*042d53a7SEvalZero if (rc == 0) {
2851*042d53a7SEvalZero good++;
2852*042d53a7SEvalZero ble_hs_cfg.sm_mitm = tmp;
2853*042d53a7SEvalZero } else if (rc != ENOENT) {
2854*042d53a7SEvalZero console_printf("invalid 'mitm_flag' parameter\n");
2855*042d53a7SEvalZero return rc;
2856*042d53a7SEvalZero }
2857*042d53a7SEvalZero
2858*042d53a7SEvalZero tmp = parse_arg_uint8("io_capabilities", &rc);
2859*042d53a7SEvalZero if (rc == 0) {
2860*042d53a7SEvalZero good++;
2861*042d53a7SEvalZero ble_hs_cfg.sm_io_cap = tmp;
2862*042d53a7SEvalZero } else if (rc != ENOENT) {
2863*042d53a7SEvalZero console_printf("invalid 'io_capabilities' parameter\n");
2864*042d53a7SEvalZero return rc;
2865*042d53a7SEvalZero }
2866*042d53a7SEvalZero
2867*042d53a7SEvalZero tmp = parse_arg_uint8("our_key_dist", &rc);
2868*042d53a7SEvalZero if (rc == 0) {
2869*042d53a7SEvalZero good++;
2870*042d53a7SEvalZero ble_hs_cfg.sm_our_key_dist = tmp;
2871*042d53a7SEvalZero } else if (rc != ENOENT) {
2872*042d53a7SEvalZero console_printf("invalid 'our_key_dist' parameter\n");
2873*042d53a7SEvalZero return rc;
2874*042d53a7SEvalZero }
2875*042d53a7SEvalZero
2876*042d53a7SEvalZero tmp = parse_arg_uint8("their_key_dist", &rc);
2877*042d53a7SEvalZero if (rc == 0) {
2878*042d53a7SEvalZero good++;
2879*042d53a7SEvalZero ble_hs_cfg.sm_their_key_dist = tmp;
2880*042d53a7SEvalZero } else if (rc != ENOENT) {
2881*042d53a7SEvalZero console_printf("invalid 'their_key_dist' parameter\n");
2882*042d53a7SEvalZero return rc;
2883*042d53a7SEvalZero }
2884*042d53a7SEvalZero
2885*042d53a7SEvalZero tmp = parse_arg_bool("bonding", &rc);
2886*042d53a7SEvalZero if (rc == 0) {
2887*042d53a7SEvalZero good++;
2888*042d53a7SEvalZero ble_hs_cfg.sm_bonding = tmp;
2889*042d53a7SEvalZero } else if (rc != ENOENT) {
2890*042d53a7SEvalZero console_printf("invalid 'bonding' parameter\n");
2891*042d53a7SEvalZero return rc;
2892*042d53a7SEvalZero }
2893*042d53a7SEvalZero
2894*042d53a7SEvalZero tmp = parse_arg_bool("sc", &rc);
2895*042d53a7SEvalZero if (rc == 0) {
2896*042d53a7SEvalZero good++;
2897*042d53a7SEvalZero ble_hs_cfg.sm_sc = tmp;
2898*042d53a7SEvalZero } else if (rc != ENOENT) {
2899*042d53a7SEvalZero console_printf("invalid 'sc' parameter\n");
2900*042d53a7SEvalZero return rc;
2901*042d53a7SEvalZero }
2902*042d53a7SEvalZero
2903*042d53a7SEvalZero if (!good) {
2904*042d53a7SEvalZero console_printf("Error: no valid settings specified\n");
2905*042d53a7SEvalZero return -1;
2906*042d53a7SEvalZero }
2907*042d53a7SEvalZero
2908*042d53a7SEvalZero return 0;
2909*042d53a7SEvalZero }
2910*042d53a7SEvalZero
2911*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2912*042d53a7SEvalZero static const struct shell_param security_set_data_params[] = {
2913*042d53a7SEvalZero {"oob_flag", "usage: =[0-1]"},
2914*042d53a7SEvalZero {"mitm_flag", "usage: =[0-1]"},
2915*042d53a7SEvalZero {"io_capabilities", "usage: =[UINT8]"},
2916*042d53a7SEvalZero {"our_key_dist", "usage: =[UINT8]"},
2917*042d53a7SEvalZero {"their_key_dist", "usage: =[UINT8]"},
2918*042d53a7SEvalZero {"bonding", "usage: =[0-1]"},
2919*042d53a7SEvalZero {"sc", "usage: =[0-1]"},
2920*042d53a7SEvalZero {NULL, NULL}
2921*042d53a7SEvalZero };
2922*042d53a7SEvalZero
2923*042d53a7SEvalZero static const struct shell_cmd_help security_set_data_help = {
2924*042d53a7SEvalZero .summary = "set security data",
2925*042d53a7SEvalZero .usage = NULL,
2926*042d53a7SEvalZero .params = security_set_data_params,
2927*042d53a7SEvalZero };
2928*042d53a7SEvalZero #endif
2929*042d53a7SEvalZero #endif
2930*042d53a7SEvalZero
2931*042d53a7SEvalZero /*****************************************************************************
2932*042d53a7SEvalZero * $test-tx *
2933*042d53a7SEvalZero * *
2934*042d53a7SEvalZero * Command to transmit 'num' packets of size 'len' at rate 'r' to
2935*042d53a7SEvalZero * handle 'h' Note that length must be <= 251. The rate is in msecs.
2936*042d53a7SEvalZero *
2937*042d53a7SEvalZero *****************************************************************************/
2938*042d53a7SEvalZero
2939*042d53a7SEvalZero static int
cmd_test_tx(int argc,char ** argv)2940*042d53a7SEvalZero cmd_test_tx(int argc, char **argv)
2941*042d53a7SEvalZero {
2942*042d53a7SEvalZero int rc;
2943*042d53a7SEvalZero uint16_t rate;
2944*042d53a7SEvalZero uint16_t len;
2945*042d53a7SEvalZero uint16_t handle;
2946*042d53a7SEvalZero uint16_t num;
2947*042d53a7SEvalZero
2948*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
2949*042d53a7SEvalZero if (rc != 0) {
2950*042d53a7SEvalZero return rc;
2951*042d53a7SEvalZero }
2952*042d53a7SEvalZero
2953*042d53a7SEvalZero rate = parse_arg_uint16("rate", &rc);
2954*042d53a7SEvalZero if (rc != 0) {
2955*042d53a7SEvalZero console_printf("invalid 'rate' parameter\n");
2956*042d53a7SEvalZero return rc;
2957*042d53a7SEvalZero }
2958*042d53a7SEvalZero
2959*042d53a7SEvalZero len = parse_arg_uint16("length", &rc);
2960*042d53a7SEvalZero if (rc != 0) {
2961*042d53a7SEvalZero console_printf("invalid 'length' parameter\n");
2962*042d53a7SEvalZero return rc;
2963*042d53a7SEvalZero }
2964*042d53a7SEvalZero if ((len > 251) || (len < 4)) {
2965*042d53a7SEvalZero console_printf("error: len must be between 4 and 251, inclusive");
2966*042d53a7SEvalZero }
2967*042d53a7SEvalZero
2968*042d53a7SEvalZero num = parse_arg_uint16("num", &rc);
2969*042d53a7SEvalZero if (rc != 0) {
2970*042d53a7SEvalZero console_printf("invalid 'num' parameter\n");
2971*042d53a7SEvalZero return rc;
2972*042d53a7SEvalZero }
2973*042d53a7SEvalZero
2974*042d53a7SEvalZero handle = parse_arg_uint16("handle", &rc);
2975*042d53a7SEvalZero if (rc != 0) {
2976*042d53a7SEvalZero console_printf("invalid 'handle' parameter\n");
2977*042d53a7SEvalZero return rc;
2978*042d53a7SEvalZero }
2979*042d53a7SEvalZero
2980*042d53a7SEvalZero rc = btshell_tx_start(handle, len, rate, num);
2981*042d53a7SEvalZero return rc;
2982*042d53a7SEvalZero }
2983*042d53a7SEvalZero
2984*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
2985*042d53a7SEvalZero static const struct shell_param test_tx_params[] = {
2986*042d53a7SEvalZero {"num", "number of packets, usage: =<UINT16>"},
2987*042d53a7SEvalZero {"length", "size of packet, usage: =<UINT16>"},
2988*042d53a7SEvalZero {"rate", "rate of tx, usage: =<UINT16>"},
2989*042d53a7SEvalZero {"handle", "handle to tx to, usage: =<UINT16>"},
2990*042d53a7SEvalZero {NULL, NULL}
2991*042d53a7SEvalZero };
2992*042d53a7SEvalZero
2993*042d53a7SEvalZero static const struct shell_cmd_help test_tx_help = {
2994*042d53a7SEvalZero .summary = "test packet transmission",
2995*042d53a7SEvalZero .usage = NULL,
2996*042d53a7SEvalZero .params = test_tx_params,
2997*042d53a7SEvalZero };
2998*042d53a7SEvalZero #endif
2999*042d53a7SEvalZero
3000*042d53a7SEvalZero /*****************************************************************************
3001*042d53a7SEvalZero * $phy-set *
3002*042d53a7SEvalZero *****************************************************************************/
3003*042d53a7SEvalZero
3004*042d53a7SEvalZero static int
cmd_phy_set(int argc,char ** argv)3005*042d53a7SEvalZero cmd_phy_set(int argc, char **argv)
3006*042d53a7SEvalZero {
3007*042d53a7SEvalZero uint16_t conn;
3008*042d53a7SEvalZero uint8_t tx_phys_mask;
3009*042d53a7SEvalZero uint8_t rx_phys_mask;
3010*042d53a7SEvalZero uint16_t phy_opts;
3011*042d53a7SEvalZero int rc;
3012*042d53a7SEvalZero
3013*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
3014*042d53a7SEvalZero if (rc != 0) {
3015*042d53a7SEvalZero return rc;
3016*042d53a7SEvalZero }
3017*042d53a7SEvalZero
3018*042d53a7SEvalZero conn = parse_arg_uint16("conn", &rc);
3019*042d53a7SEvalZero if (rc != 0) {
3020*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
3021*042d53a7SEvalZero return rc;
3022*042d53a7SEvalZero }
3023*042d53a7SEvalZero
3024*042d53a7SEvalZero tx_phys_mask = parse_arg_uint8("tx_phys_mask", &rc);
3025*042d53a7SEvalZero if (rc != 0) {
3026*042d53a7SEvalZero console_printf("invalid 'tx_phys_mask' parameter\n");
3027*042d53a7SEvalZero return rc;
3028*042d53a7SEvalZero }
3029*042d53a7SEvalZero
3030*042d53a7SEvalZero rx_phys_mask = parse_arg_uint8("rx_phys_mask", &rc);
3031*042d53a7SEvalZero if (rc != 0) {
3032*042d53a7SEvalZero console_printf("invalid 'rx_phys_mask' parameter\n");
3033*042d53a7SEvalZero return rc;
3034*042d53a7SEvalZero }
3035*042d53a7SEvalZero
3036*042d53a7SEvalZero phy_opts = parse_arg_uint16("phy_opts", &rc);
3037*042d53a7SEvalZero if (rc != 0) {
3038*042d53a7SEvalZero console_printf("invalid 'phy_opts' parameter\n");
3039*042d53a7SEvalZero return rc;
3040*042d53a7SEvalZero }
3041*042d53a7SEvalZero
3042*042d53a7SEvalZero return ble_gap_set_prefered_le_phy(conn, tx_phys_mask, rx_phys_mask,
3043*042d53a7SEvalZero phy_opts);
3044*042d53a7SEvalZero }
3045*042d53a7SEvalZero
3046*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3047*042d53a7SEvalZero static const struct shell_param phy_set_params[] = {
3048*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3049*042d53a7SEvalZero {"tx_phys_mask", "usage: =<UINT8>"},
3050*042d53a7SEvalZero {"rx_phys_mask", "usage: =<UINT8>"},
3051*042d53a7SEvalZero {"phy_opts", "usage: =<UINT16>"},
3052*042d53a7SEvalZero {NULL, NULL}
3053*042d53a7SEvalZero };
3054*042d53a7SEvalZero
3055*042d53a7SEvalZero static const struct shell_cmd_help phy_set_help = {
3056*042d53a7SEvalZero .summary = "set preferred PHYs",
3057*042d53a7SEvalZero .usage = NULL,
3058*042d53a7SEvalZero .params = phy_set_params,
3059*042d53a7SEvalZero };
3060*042d53a7SEvalZero #endif
3061*042d53a7SEvalZero
3062*042d53a7SEvalZero /*****************************************************************************
3063*042d53a7SEvalZero * $phy-set-default *
3064*042d53a7SEvalZero *****************************************************************************/
3065*042d53a7SEvalZero
3066*042d53a7SEvalZero static int
cmd_phy_set_default(int argc,char ** argv)3067*042d53a7SEvalZero cmd_phy_set_default(int argc, char **argv)
3068*042d53a7SEvalZero {
3069*042d53a7SEvalZero uint8_t tx_phys_mask;
3070*042d53a7SEvalZero uint8_t rx_phys_mask;
3071*042d53a7SEvalZero int rc;
3072*042d53a7SEvalZero
3073*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
3074*042d53a7SEvalZero if (rc != 0) {
3075*042d53a7SEvalZero return rc;
3076*042d53a7SEvalZero }
3077*042d53a7SEvalZero
3078*042d53a7SEvalZero tx_phys_mask = parse_arg_uint8("tx_phys_mask", &rc);
3079*042d53a7SEvalZero if (rc != 0) {
3080*042d53a7SEvalZero console_printf("invalid 'tx_phys_mask' parameter\n");
3081*042d53a7SEvalZero return rc;
3082*042d53a7SEvalZero }
3083*042d53a7SEvalZero
3084*042d53a7SEvalZero rx_phys_mask = parse_arg_uint8("rx_phys_mask", &rc);
3085*042d53a7SEvalZero if (rc != 0) {
3086*042d53a7SEvalZero console_printf("invalid 'rx_phys_mask' parameter\n");
3087*042d53a7SEvalZero return rc;
3088*042d53a7SEvalZero }
3089*042d53a7SEvalZero
3090*042d53a7SEvalZero return ble_gap_set_prefered_default_le_phy(tx_phys_mask, rx_phys_mask);
3091*042d53a7SEvalZero }
3092*042d53a7SEvalZero
3093*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3094*042d53a7SEvalZero static const struct shell_param phy_set_default_params[] = {
3095*042d53a7SEvalZero {"tx_phys_mask", "usage: =<UINT8>"},
3096*042d53a7SEvalZero {"rx_phys_mask", "usage: =<UINT8>"},
3097*042d53a7SEvalZero {NULL, NULL}
3098*042d53a7SEvalZero };
3099*042d53a7SEvalZero
3100*042d53a7SEvalZero static const struct shell_cmd_help phy_set_default_help = {
3101*042d53a7SEvalZero .summary = "set preferred default PHYs",
3102*042d53a7SEvalZero .usage = NULL,
3103*042d53a7SEvalZero .params = phy_set_default_params,
3104*042d53a7SEvalZero };
3105*042d53a7SEvalZero #endif
3106*042d53a7SEvalZero
3107*042d53a7SEvalZero /*****************************************************************************
3108*042d53a7SEvalZero * $phy-read *
3109*042d53a7SEvalZero *****************************************************************************/
3110*042d53a7SEvalZero
3111*042d53a7SEvalZero static int
cmd_phy_read(int argc,char ** argv)3112*042d53a7SEvalZero cmd_phy_read(int argc, char **argv)
3113*042d53a7SEvalZero {
3114*042d53a7SEvalZero uint16_t conn = 0;
3115*042d53a7SEvalZero uint8_t tx_phy;
3116*042d53a7SEvalZero uint8_t rx_phy;
3117*042d53a7SEvalZero int rc;
3118*042d53a7SEvalZero
3119*042d53a7SEvalZero rc = parse_arg_all(argc - 1, argv + 1);
3120*042d53a7SEvalZero if (rc != 0) {
3121*042d53a7SEvalZero return rc;
3122*042d53a7SEvalZero }
3123*042d53a7SEvalZero
3124*042d53a7SEvalZero conn = parse_arg_uint16("conn", &rc);
3125*042d53a7SEvalZero if (rc != 0) {
3126*042d53a7SEvalZero console_printf("invalid 'conn' parameter\n");
3127*042d53a7SEvalZero return rc;
3128*042d53a7SEvalZero }
3129*042d53a7SEvalZero
3130*042d53a7SEvalZero rc = ble_gap_read_le_phy(conn, &tx_phy, &rx_phy);
3131*042d53a7SEvalZero if (rc != 0) {
3132*042d53a7SEvalZero console_printf("Could not read PHY error: %d\n", rc);
3133*042d53a7SEvalZero return rc;
3134*042d53a7SEvalZero }
3135*042d53a7SEvalZero
3136*042d53a7SEvalZero console_printf("TX_PHY: %d\n", tx_phy);
3137*042d53a7SEvalZero console_printf("RX_PHY: %d\n", tx_phy);
3138*042d53a7SEvalZero
3139*042d53a7SEvalZero return 0;
3140*042d53a7SEvalZero }
3141*042d53a7SEvalZero
3142*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3143*042d53a7SEvalZero static const struct shell_param phy_read_params[] = {
3144*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3145*042d53a7SEvalZero {NULL, NULL}
3146*042d53a7SEvalZero };
3147*042d53a7SEvalZero
3148*042d53a7SEvalZero static const struct shell_cmd_help phy_read_help = {
3149*042d53a7SEvalZero .summary = "read PHYs",
3150*042d53a7SEvalZero .usage = NULL,
3151*042d53a7SEvalZero .params = phy_read_params,
3152*042d53a7SEvalZero };
3153*042d53a7SEvalZero #endif
3154*042d53a7SEvalZero
3155*042d53a7SEvalZero /*****************************************************************************
3156*042d53a7SEvalZero * $host-enable *
3157*042d53a7SEvalZero *****************************************************************************/
3158*042d53a7SEvalZero
3159*042d53a7SEvalZero static int
cmd_host_enable(int argc,char ** argv)3160*042d53a7SEvalZero cmd_host_enable(int argc, char **argv)
3161*042d53a7SEvalZero {
3162*042d53a7SEvalZero ble_hs_sched_start();
3163*042d53a7SEvalZero
3164*042d53a7SEvalZero return 0;
3165*042d53a7SEvalZero }
3166*042d53a7SEvalZero
3167*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3168*042d53a7SEvalZero static const struct shell_cmd_help host_enable_help = {
3169*042d53a7SEvalZero .summary = "start the NimBLE host",
3170*042d53a7SEvalZero .usage = NULL,
3171*042d53a7SEvalZero .params = NULL,
3172*042d53a7SEvalZero };
3173*042d53a7SEvalZero #endif
3174*042d53a7SEvalZero
3175*042d53a7SEvalZero /*****************************************************************************
3176*042d53a7SEvalZero * $host-disable *
3177*042d53a7SEvalZero *****************************************************************************/
3178*042d53a7SEvalZero
3179*042d53a7SEvalZero static void
on_stop(int status,void * arg)3180*042d53a7SEvalZero on_stop(int status, void *arg)
3181*042d53a7SEvalZero {
3182*042d53a7SEvalZero if (status == 0) {
3183*042d53a7SEvalZero console_printf("host stopped\n");
3184*042d53a7SEvalZero } else {
3185*042d53a7SEvalZero console_printf("host failed to stop; rc=%d\n", status);
3186*042d53a7SEvalZero }
3187*042d53a7SEvalZero }
3188*042d53a7SEvalZero
3189*042d53a7SEvalZero static int
cmd_host_disable(int argc,char ** argv)3190*042d53a7SEvalZero cmd_host_disable(int argc, char **argv)
3191*042d53a7SEvalZero {
3192*042d53a7SEvalZero static struct ble_hs_stop_listener listener;
3193*042d53a7SEvalZero int rc;
3194*042d53a7SEvalZero
3195*042d53a7SEvalZero rc = ble_hs_stop(&listener, on_stop, NULL);
3196*042d53a7SEvalZero return rc;
3197*042d53a7SEvalZero }
3198*042d53a7SEvalZero
3199*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3200*042d53a7SEvalZero static const struct shell_cmd_help host_disable_help = {
3201*042d53a7SEvalZero .summary = "stop the NimBLE host",
3202*042d53a7SEvalZero .usage = NULL,
3203*042d53a7SEvalZero .params = NULL,
3204*042d53a7SEvalZero };
3205*042d53a7SEvalZero #endif
3206*042d53a7SEvalZero
3207*042d53a7SEvalZero /*****************************************************************************
3208*042d53a7SEvalZero * $gatt-discover *
3209*042d53a7SEvalZero *****************************************************************************/
3210*042d53a7SEvalZero
3211*042d53a7SEvalZero static const struct shell_param gatt_discover_characteristic_params[] = {
3212*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3213*042d53a7SEvalZero {"uuid", "discover by uuid, usage: =[UUID]"},
3214*042d53a7SEvalZero {"start", "start handle, usage: =<UINT16>"},
3215*042d53a7SEvalZero {"end", "end handle, usage: =<UINT16>"},
3216*042d53a7SEvalZero {NULL, NULL}
3217*042d53a7SEvalZero };
3218*042d53a7SEvalZero
3219*042d53a7SEvalZero static const struct shell_cmd_help gatt_discover_characteristic_help = {
3220*042d53a7SEvalZero .summary = "perform characteristic discovery procedure",
3221*042d53a7SEvalZero .usage = NULL,
3222*042d53a7SEvalZero .params = gatt_discover_characteristic_params,
3223*042d53a7SEvalZero };
3224*042d53a7SEvalZero
3225*042d53a7SEvalZero static const struct shell_param gatt_discover_descriptor_params[] = {
3226*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3227*042d53a7SEvalZero {"start", "start handle, usage: =<UINT16>"},
3228*042d53a7SEvalZero {"end", "end handle, usage: =<UINT16>"},
3229*042d53a7SEvalZero {NULL, NULL}
3230*042d53a7SEvalZero };
3231*042d53a7SEvalZero
3232*042d53a7SEvalZero static const struct shell_cmd_help gatt_discover_descriptor_help = {
3233*042d53a7SEvalZero .summary = "perform descriptor discovery procedure",
3234*042d53a7SEvalZero .usage = NULL,
3235*042d53a7SEvalZero .params = gatt_discover_descriptor_params,
3236*042d53a7SEvalZero };
3237*042d53a7SEvalZero
3238*042d53a7SEvalZero static const struct shell_param gatt_discover_service_params[] = {
3239*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3240*042d53a7SEvalZero {"uuid", "discover by uuid, usage: =[UUID]"},
3241*042d53a7SEvalZero {NULL, NULL}
3242*042d53a7SEvalZero };
3243*042d53a7SEvalZero
3244*042d53a7SEvalZero static const struct shell_cmd_help gatt_discover_service_help = {
3245*042d53a7SEvalZero .summary = "perform service discovery procedure",
3246*042d53a7SEvalZero .usage = NULL,
3247*042d53a7SEvalZero .params = gatt_discover_service_params,
3248*042d53a7SEvalZero };
3249*042d53a7SEvalZero
3250*042d53a7SEvalZero static const struct shell_param gatt_discover_full_params[] = {
3251*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3252*042d53a7SEvalZero {NULL, NULL}
3253*042d53a7SEvalZero };
3254*042d53a7SEvalZero
3255*042d53a7SEvalZero static const struct shell_cmd_help gatt_discover_full_help = {
3256*042d53a7SEvalZero .summary = "perform full discovery procedure",
3257*042d53a7SEvalZero .usage = NULL,
3258*042d53a7SEvalZero .params = gatt_discover_full_params,
3259*042d53a7SEvalZero };
3260*042d53a7SEvalZero
3261*042d53a7SEvalZero /*****************************************************************************
3262*042d53a7SEvalZero * $gatt-exchange-mtu *
3263*042d53a7SEvalZero *****************************************************************************/
3264*042d53a7SEvalZero
3265*042d53a7SEvalZero static const struct shell_param gatt_exchange_mtu_params[] = {
3266*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3267*042d53a7SEvalZero {NULL, NULL}
3268*042d53a7SEvalZero };
3269*042d53a7SEvalZero
3270*042d53a7SEvalZero static const struct shell_cmd_help gatt_exchange_mtu_help = {
3271*042d53a7SEvalZero .summary = "perform mtu exchange procedure",
3272*042d53a7SEvalZero .usage = NULL,
3273*042d53a7SEvalZero .params = gatt_exchange_mtu_params,
3274*042d53a7SEvalZero };
3275*042d53a7SEvalZero
3276*042d53a7SEvalZero /*****************************************************************************
3277*042d53a7SEvalZero * $gatt-find-included-services *
3278*042d53a7SEvalZero *****************************************************************************/
3279*042d53a7SEvalZero
3280*042d53a7SEvalZero static const struct shell_param gatt_find_included_services_params[] = {
3281*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3282*042d53a7SEvalZero {"start", "start handle, usage: =<UINT16>"},
3283*042d53a7SEvalZero {"end", "end handle, usage: =<UINT16>"},
3284*042d53a7SEvalZero {NULL, NULL}
3285*042d53a7SEvalZero };
3286*042d53a7SEvalZero
3287*042d53a7SEvalZero static const struct shell_cmd_help gatt_find_included_services_help = {
3288*042d53a7SEvalZero .summary = "perform find included services procedure",
3289*042d53a7SEvalZero .usage = NULL,
3290*042d53a7SEvalZero .params = gatt_find_included_services_params,
3291*042d53a7SEvalZero };
3292*042d53a7SEvalZero
3293*042d53a7SEvalZero /*****************************************************************************
3294*042d53a7SEvalZero * $gatt-notify *
3295*042d53a7SEvalZero *****************************************************************************/
3296*042d53a7SEvalZero
3297*042d53a7SEvalZero static const struct shell_param gatt_notify_params[] = {
3298*042d53a7SEvalZero {"attr", "attribute handle, usage: =<UINT16>"},
3299*042d53a7SEvalZero {NULL, NULL}
3300*042d53a7SEvalZero };
3301*042d53a7SEvalZero
3302*042d53a7SEvalZero static const struct shell_cmd_help gatt_notify_help = {
3303*042d53a7SEvalZero .summary = "notify about attribute value changed",
3304*042d53a7SEvalZero .usage = NULL,
3305*042d53a7SEvalZero .params = gatt_notify_params,
3306*042d53a7SEvalZero };
3307*042d53a7SEvalZero
3308*042d53a7SEvalZero /*****************************************************************************
3309*042d53a7SEvalZero * $gatt-read *
3310*042d53a7SEvalZero *****************************************************************************/
3311*042d53a7SEvalZero
3312*042d53a7SEvalZero static const struct shell_param gatt_read_params[] = {
3313*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3314*042d53a7SEvalZero {"long", "is read long, usage: =[0-1], default=0"},
3315*042d53a7SEvalZero {"attr", "attribute handle, usage: =<UINT16>"},
3316*042d53a7SEvalZero {"offset", "offset value, usage: =<UINT16>"},
3317*042d53a7SEvalZero {"uuid", "read by uuid, usage: =[UUID]"},
3318*042d53a7SEvalZero {"start", "start handle, usage: =<UINT16>"},
3319*042d53a7SEvalZero {"end", "end handle, usage: =<UINT16>"},
3320*042d53a7SEvalZero {NULL, NULL}
3321*042d53a7SEvalZero };
3322*042d53a7SEvalZero
3323*042d53a7SEvalZero static const struct shell_cmd_help gatt_read_help = {
3324*042d53a7SEvalZero .summary = "perform gatt read procedure",
3325*042d53a7SEvalZero .usage = NULL,
3326*042d53a7SEvalZero .params = gatt_read_params,
3327*042d53a7SEvalZero };
3328*042d53a7SEvalZero
3329*042d53a7SEvalZero /*****************************************************************************
3330*042d53a7SEvalZero * $gatt-service-changed *
3331*042d53a7SEvalZero *****************************************************************************/
3332*042d53a7SEvalZero
3333*042d53a7SEvalZero static const struct shell_param gatt_service_changed_params[] = {
3334*042d53a7SEvalZero {"start", "start handle, usage: =<UINT16>"},
3335*042d53a7SEvalZero {"end", "end handle, usage: =<UINT16>"},
3336*042d53a7SEvalZero {NULL, NULL}
3337*042d53a7SEvalZero };
3338*042d53a7SEvalZero
3339*042d53a7SEvalZero static const struct shell_cmd_help gatt_service_changed_help = {
3340*042d53a7SEvalZero .summary = "send service changed indication",
3341*042d53a7SEvalZero .usage = NULL,
3342*042d53a7SEvalZero .params = gatt_service_changed_params,
3343*042d53a7SEvalZero };
3344*042d53a7SEvalZero
3345*042d53a7SEvalZero /*****************************************************************************
3346*042d53a7SEvalZero * $gatt-service-visibility *
3347*042d53a7SEvalZero *****************************************************************************/
3348*042d53a7SEvalZero
3349*042d53a7SEvalZero static const struct shell_param gatt_service_visibility_params[] = {
3350*042d53a7SEvalZero {"handle", "usage: =<UINT16>"},
3351*042d53a7SEvalZero {"visibility", "usage: =<0-1>"},
3352*042d53a7SEvalZero {NULL, NULL}
3353*042d53a7SEvalZero };
3354*042d53a7SEvalZero
3355*042d53a7SEvalZero static const struct shell_cmd_help gatt_service_visibility_help = {
3356*042d53a7SEvalZero .summary = "change service visibility",
3357*042d53a7SEvalZero .usage = NULL,
3358*042d53a7SEvalZero .params = gatt_service_visibility_params,
3359*042d53a7SEvalZero };
3360*042d53a7SEvalZero
3361*042d53a7SEvalZero /*****************************************************************************
3362*042d53a7SEvalZero * $gatt-show *
3363*042d53a7SEvalZero *****************************************************************************/
3364*042d53a7SEvalZero
3365*042d53a7SEvalZero static const struct shell_param gatt_show_params[] = {
3366*042d53a7SEvalZero {NULL, NULL}
3367*042d53a7SEvalZero };
3368*042d53a7SEvalZero
3369*042d53a7SEvalZero static const struct shell_cmd_help gatt_show_help = {
3370*042d53a7SEvalZero .summary = "show discovered gatt database",
3371*042d53a7SEvalZero .usage = NULL,
3372*042d53a7SEvalZero .params = gatt_show_params,
3373*042d53a7SEvalZero };
3374*042d53a7SEvalZero
3375*042d53a7SEvalZero static const struct shell_cmd_help gatt_show_local_help = {
3376*042d53a7SEvalZero .summary = "show local gatt database",
3377*042d53a7SEvalZero .usage = NULL,
3378*042d53a7SEvalZero .params = gatt_show_params,
3379*042d53a7SEvalZero };
3380*042d53a7SEvalZero
3381*042d53a7SEvalZero static const struct shell_cmd_help gatt_show_addr_help = {
3382*042d53a7SEvalZero .summary = "show device address",
3383*042d53a7SEvalZero .usage = NULL,
3384*042d53a7SEvalZero .params = gatt_show_params,
3385*042d53a7SEvalZero };
3386*042d53a7SEvalZero
3387*042d53a7SEvalZero static const struct shell_cmd_help gatt_show_conn_help = {
3388*042d53a7SEvalZero .summary = "show connections information",
3389*042d53a7SEvalZero .usage = NULL,
3390*042d53a7SEvalZero .params = gatt_show_params,
3391*042d53a7SEvalZero };
3392*042d53a7SEvalZero
3393*042d53a7SEvalZero /*****************************************************************************
3394*042d53a7SEvalZero * $gatt-write *
3395*042d53a7SEvalZero *****************************************************************************/
3396*042d53a7SEvalZero
3397*042d53a7SEvalZero static const struct shell_param gatt_write_params[] = {
3398*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3399*042d53a7SEvalZero {"no_rsp", "write without response, usage: =[0-1], default=0"},
3400*042d53a7SEvalZero {"long", "is write long, usage: =[0-1], default=0"},
3401*042d53a7SEvalZero {"attr", "attribute handle, usage: =<UINT16>"},
3402*042d53a7SEvalZero {"offset", "attribute handle, usage: =<UINT16>"},
3403*042d53a7SEvalZero {"value", "usage: =<octets>"},
3404*042d53a7SEvalZero {NULL, NULL}
3405*042d53a7SEvalZero };
3406*042d53a7SEvalZero
3407*042d53a7SEvalZero static const struct shell_cmd_help gatt_write_help = {
3408*042d53a7SEvalZero .summary = "perform gatt write procedure",
3409*042d53a7SEvalZero .usage = NULL,
3410*042d53a7SEvalZero .params = gatt_write_params,
3411*042d53a7SEvalZero };
3412*042d53a7SEvalZero
3413*042d53a7SEvalZero #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
3414*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3415*042d53a7SEvalZero /*****************************************************************************
3416*042d53a7SEvalZero * $l2cap-update *
3417*042d53a7SEvalZero *****************************************************************************/
3418*042d53a7SEvalZero
3419*042d53a7SEvalZero static const struct shell_param l2cap_update_params[] = {
3420*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3421*042d53a7SEvalZero {"interval_min", "usage: =[0-UINT16_MAX], default: 30"},
3422*042d53a7SEvalZero {"interval_max", "usage: =[0-UINT16_MAX], default: 50"},
3423*042d53a7SEvalZero {"latency", "usage: =[UINT16], default: 0"},
3424*042d53a7SEvalZero {"timeout", "usage: =[UINT16], default: 0x0100"},
3425*042d53a7SEvalZero {NULL, NULL}
3426*042d53a7SEvalZero };
3427*042d53a7SEvalZero
3428*042d53a7SEvalZero static const struct shell_cmd_help l2cap_update_help = {
3429*042d53a7SEvalZero .summary = "update l2cap parameters for connection",
3430*042d53a7SEvalZero .usage = NULL,
3431*042d53a7SEvalZero .params = l2cap_update_params,
3432*042d53a7SEvalZero };
3433*042d53a7SEvalZero
3434*042d53a7SEvalZero /*****************************************************************************
3435*042d53a7SEvalZero * $l2cap-create-server *
3436*042d53a7SEvalZero *****************************************************************************/
3437*042d53a7SEvalZero
3438*042d53a7SEvalZero static const struct shell_param l2cap_create_server_params[] = {
3439*042d53a7SEvalZero {"psm", "usage: =<UINT16>"},
3440*042d53a7SEvalZero {"error", "usage: used for PTS testing:"},
3441*042d53a7SEvalZero {"", "0 - always accept"},
3442*042d53a7SEvalZero {"", "1 - reject with insufficient authentication"},
3443*042d53a7SEvalZero {"", "2 - reject with insufficient authorization"},
3444*042d53a7SEvalZero {"", "3 - reject with insufficient key size"},
3445*042d53a7SEvalZero {NULL, NULL}
3446*042d53a7SEvalZero };
3447*042d53a7SEvalZero
3448*042d53a7SEvalZero static const struct shell_cmd_help l2cap_create_server_help = {
3449*042d53a7SEvalZero .summary = "create l2cap server",
3450*042d53a7SEvalZero .usage = NULL,
3451*042d53a7SEvalZero .params = l2cap_create_server_params,
3452*042d53a7SEvalZero };
3453*042d53a7SEvalZero
3454*042d53a7SEvalZero /*****************************************************************************
3455*042d53a7SEvalZero * $l2cap-connect *
3456*042d53a7SEvalZero *****************************************************************************/
3457*042d53a7SEvalZero
3458*042d53a7SEvalZero static const struct shell_param l2cap_connect_params[] = {
3459*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3460*042d53a7SEvalZero {"psm", "usage: =<UINT16>"},
3461*042d53a7SEvalZero {NULL, NULL}
3462*042d53a7SEvalZero };
3463*042d53a7SEvalZero
3464*042d53a7SEvalZero static const struct shell_cmd_help l2cap_connect_help = {
3465*042d53a7SEvalZero .summary = "perform l2cap connect procedure",
3466*042d53a7SEvalZero .usage = NULL,
3467*042d53a7SEvalZero .params = l2cap_connect_params,
3468*042d53a7SEvalZero };
3469*042d53a7SEvalZero
3470*042d53a7SEvalZero /*****************************************************************************
3471*042d53a7SEvalZero * $l2cap-disconnect *
3472*042d53a7SEvalZero *****************************************************************************/
3473*042d53a7SEvalZero
3474*042d53a7SEvalZero static const struct shell_param l2cap_disconnect_params[] = {
3475*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3476*042d53a7SEvalZero {"idx", "usage: =<UINT16>"},
3477*042d53a7SEvalZero {NULL, NULL}
3478*042d53a7SEvalZero };
3479*042d53a7SEvalZero
3480*042d53a7SEvalZero static const struct shell_cmd_help l2cap_disconnect_help = {
3481*042d53a7SEvalZero .summary = "perform l2cap disconnect procedure",
3482*042d53a7SEvalZero .usage = "use gatt-show-coc to get the parameters",
3483*042d53a7SEvalZero .params = l2cap_disconnect_params,
3484*042d53a7SEvalZero };
3485*042d53a7SEvalZero
3486*042d53a7SEvalZero /*****************************************************************************
3487*042d53a7SEvalZero * $l2cap-send *
3488*042d53a7SEvalZero *****************************************************************************/
3489*042d53a7SEvalZero
3490*042d53a7SEvalZero static const struct shell_param l2cap_send_params[] = {
3491*042d53a7SEvalZero {"conn", "connection handle, usage: =<UINT16>"},
3492*042d53a7SEvalZero {"idx", "usage: =<UINT16>"},
3493*042d53a7SEvalZero {"bytes", "number of bytes to send, usage: =<UINT16>"},
3494*042d53a7SEvalZero {NULL, NULL}
3495*042d53a7SEvalZero };
3496*042d53a7SEvalZero
3497*042d53a7SEvalZero static const struct shell_cmd_help l2cap_send_help = {
3498*042d53a7SEvalZero .summary = "perform l2cap send procedure",
3499*042d53a7SEvalZero .usage = "use l2cap-show-coc to get the parameters",
3500*042d53a7SEvalZero .params = l2cap_send_params,
3501*042d53a7SEvalZero };
3502*042d53a7SEvalZero
3503*042d53a7SEvalZero /*****************************************************************************
3504*042d53a7SEvalZero * $l2cap-show-coc *
3505*042d53a7SEvalZero *****************************************************************************/
3506*042d53a7SEvalZero
3507*042d53a7SEvalZero static const struct shell_param l2cap_show_coc_params[] = {
3508*042d53a7SEvalZero {NULL, NULL}
3509*042d53a7SEvalZero };
3510*042d53a7SEvalZero
3511*042d53a7SEvalZero static const struct shell_cmd_help l2cap_show_coc_help = {
3512*042d53a7SEvalZero .summary = "show coc information",
3513*042d53a7SEvalZero .usage = NULL,
3514*042d53a7SEvalZero .params = l2cap_show_coc_params,
3515*042d53a7SEvalZero };
3516*042d53a7SEvalZero
3517*042d53a7SEvalZero #endif
3518*042d53a7SEvalZero #endif
3519*042d53a7SEvalZero
3520*042d53a7SEvalZero static const struct shell_cmd btshell_commands[] = {
3521*042d53a7SEvalZero #if MYNEWT_VAL(BLE_EXT_ADV)
3522*042d53a7SEvalZero {
3523*042d53a7SEvalZero .sc_cmd = "advertise-configure",
3524*042d53a7SEvalZero .sc_cmd_func = cmd_advertise_configure,
3525*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3526*042d53a7SEvalZero .help = &advertise_configure_help,
3527*042d53a7SEvalZero #endif
3528*042d53a7SEvalZero },
3529*042d53a7SEvalZero {
3530*042d53a7SEvalZero .sc_cmd = "advertise-set-addr",
3531*042d53a7SEvalZero .sc_cmd_func = cmd_advertise_set_addr,
3532*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3533*042d53a7SEvalZero .help = &advertise_set_addr_help,
3534*042d53a7SEvalZero #endif
3535*042d53a7SEvalZero },
3536*042d53a7SEvalZero {
3537*042d53a7SEvalZero .sc_cmd = "advertise-set-adv-data",
3538*042d53a7SEvalZero .sc_cmd_func = cmd_set_adv_data,
3539*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3540*042d53a7SEvalZero .help = &set_adv_data_help,
3541*042d53a7SEvalZero #endif
3542*042d53a7SEvalZero },
3543*042d53a7SEvalZero {
3544*042d53a7SEvalZero .sc_cmd = "advertise-set-scan-rsp",
3545*042d53a7SEvalZero .sc_cmd_func = cmd_set_scan_rsp,
3546*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3547*042d53a7SEvalZero .help = &set_scan_rsp_help,
3548*042d53a7SEvalZero #endif
3549*042d53a7SEvalZero },
3550*042d53a7SEvalZero {
3551*042d53a7SEvalZero .sc_cmd = "advertise-start",
3552*042d53a7SEvalZero .sc_cmd_func = cmd_advertise_start,
3553*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3554*042d53a7SEvalZero .help = &advertise_start_help,
3555*042d53a7SEvalZero #endif
3556*042d53a7SEvalZero },
3557*042d53a7SEvalZero {
3558*042d53a7SEvalZero .sc_cmd = "advertise-stop",
3559*042d53a7SEvalZero .sc_cmd_func = cmd_advertise_stop,
3560*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3561*042d53a7SEvalZero .help = &advertise_stop_help,
3562*042d53a7SEvalZero #endif
3563*042d53a7SEvalZero },
3564*042d53a7SEvalZero {
3565*042d53a7SEvalZero .sc_cmd = "advertise-remove",
3566*042d53a7SEvalZero .sc_cmd_func = cmd_advertise_remove,
3567*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3568*042d53a7SEvalZero .help = &advertise_remove_help,
3569*042d53a7SEvalZero #endif
3570*042d53a7SEvalZero },
3571*042d53a7SEvalZero #else
3572*042d53a7SEvalZero {
3573*042d53a7SEvalZero .sc_cmd = "advertise",
3574*042d53a7SEvalZero .sc_cmd_func = cmd_advertise,
3575*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3576*042d53a7SEvalZero .help = &advertise_help,
3577*042d53a7SEvalZero #endif
3578*042d53a7SEvalZero },
3579*042d53a7SEvalZero #endif
3580*042d53a7SEvalZero {
3581*042d53a7SEvalZero .sc_cmd = "connect",
3582*042d53a7SEvalZero .sc_cmd_func = cmd_connect,
3583*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3584*042d53a7SEvalZero .help = &connect_help,
3585*042d53a7SEvalZero #endif
3586*042d53a7SEvalZero },
3587*042d53a7SEvalZero {
3588*042d53a7SEvalZero .sc_cmd = "disconnect",
3589*042d53a7SEvalZero .sc_cmd_func = cmd_disconnect,
3590*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3591*042d53a7SEvalZero .help = &disconnect_help,
3592*042d53a7SEvalZero #endif
3593*042d53a7SEvalZero },
3594*042d53a7SEvalZero {
3595*042d53a7SEvalZero .sc_cmd = "show-addr",
3596*042d53a7SEvalZero .sc_cmd_func = cmd_show_addr,
3597*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3598*042d53a7SEvalZero .help = &gatt_show_addr_help,
3599*042d53a7SEvalZero #endif
3600*042d53a7SEvalZero },
3601*042d53a7SEvalZero {
3602*042d53a7SEvalZero .sc_cmd = "show-conn",
3603*042d53a7SEvalZero .sc_cmd_func = cmd_show_conn,
3604*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3605*042d53a7SEvalZero .help = &gatt_show_conn_help,
3606*042d53a7SEvalZero #endif
3607*042d53a7SEvalZero },
3608*042d53a7SEvalZero {
3609*042d53a7SEvalZero .sc_cmd = "set-scan-opts",
3610*042d53a7SEvalZero .sc_cmd_func = cmd_set_scan_opts,
3611*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3612*042d53a7SEvalZero .help = &set_scan_opts_help,
3613*042d53a7SEvalZero #endif
3614*042d53a7SEvalZero },
3615*042d53a7SEvalZero {
3616*042d53a7SEvalZero .sc_cmd = "scan",
3617*042d53a7SEvalZero .sc_cmd_func = cmd_scan,
3618*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3619*042d53a7SEvalZero .help = &scan_help,
3620*042d53a7SEvalZero #endif
3621*042d53a7SEvalZero },
3622*042d53a7SEvalZero {
3623*042d53a7SEvalZero .sc_cmd = "set",
3624*042d53a7SEvalZero .sc_cmd_func = cmd_set,
3625*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3626*042d53a7SEvalZero .help = &set_help,
3627*042d53a7SEvalZero #endif
3628*042d53a7SEvalZero },
3629*042d53a7SEvalZero #if !MYNEWT_VAL(BLE_EXT_ADV)
3630*042d53a7SEvalZero {
3631*042d53a7SEvalZero .sc_cmd = "set-adv-data",
3632*042d53a7SEvalZero .sc_cmd_func = cmd_set_adv_data,
3633*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3634*042d53a7SEvalZero .help = &set_adv_data_help,
3635*042d53a7SEvalZero #endif
3636*042d53a7SEvalZero },
3637*042d53a7SEvalZero {
3638*042d53a7SEvalZero .sc_cmd = "set-scan-rsp",
3639*042d53a7SEvalZero .sc_cmd_func = cmd_set_scan_rsp,
3640*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3641*042d53a7SEvalZero .help = &set_scan_rsp_help,
3642*042d53a7SEvalZero #endif
3643*042d53a7SEvalZero },
3644*042d53a7SEvalZero #endif
3645*042d53a7SEvalZero {
3646*042d53a7SEvalZero .sc_cmd = "set-priv-mode",
3647*042d53a7SEvalZero .sc_cmd_func = cmd_set_priv_mode,
3648*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3649*042d53a7SEvalZero .help = &set_priv_mode_help,
3650*042d53a7SEvalZero #endif
3651*042d53a7SEvalZero },
3652*042d53a7SEvalZero {
3653*042d53a7SEvalZero .sc_cmd = "white-list",
3654*042d53a7SEvalZero .sc_cmd_func = cmd_white_list,
3655*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3656*042d53a7SEvalZero .help = &white_list_help,
3657*042d53a7SEvalZero #endif
3658*042d53a7SEvalZero },
3659*042d53a7SEvalZero {
3660*042d53a7SEvalZero .sc_cmd = "conn-rssi",
3661*042d53a7SEvalZero .sc_cmd_func = cmd_conn_rssi,
3662*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3663*042d53a7SEvalZero .help = &conn_rssi_help,
3664*042d53a7SEvalZero #endif
3665*042d53a7SEvalZero },
3666*042d53a7SEvalZero {
3667*042d53a7SEvalZero .sc_cmd = "conn-update-params",
3668*042d53a7SEvalZero .sc_cmd_func = cmd_conn_update_params,
3669*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3670*042d53a7SEvalZero .help = &conn_update_params_help,
3671*042d53a7SEvalZero #endif
3672*042d53a7SEvalZero },
3673*042d53a7SEvalZero {
3674*042d53a7SEvalZero .sc_cmd = "conn-datalen",
3675*042d53a7SEvalZero .sc_cmd_func = cmd_conn_datalen,
3676*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3677*042d53a7SEvalZero .help = &conn_datalen_help,
3678*042d53a7SEvalZero #endif
3679*042d53a7SEvalZero },
3680*042d53a7SEvalZero {
3681*042d53a7SEvalZero .sc_cmd = "gatt-discover-characteristic",
3682*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_discover_characteristic,
3683*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3684*042d53a7SEvalZero .help = &gatt_discover_characteristic_help,
3685*042d53a7SEvalZero #endif
3686*042d53a7SEvalZero },
3687*042d53a7SEvalZero {
3688*042d53a7SEvalZero .sc_cmd = "gatt-discover-descriptor",
3689*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_discover_descriptor,
3690*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3691*042d53a7SEvalZero .help = &gatt_discover_descriptor_help,
3692*042d53a7SEvalZero #endif
3693*042d53a7SEvalZero },
3694*042d53a7SEvalZero {
3695*042d53a7SEvalZero .sc_cmd = "gatt-discover-service",
3696*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_discover_service,
3697*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3698*042d53a7SEvalZero .help = &gatt_discover_service_help,
3699*042d53a7SEvalZero #endif
3700*042d53a7SEvalZero },
3701*042d53a7SEvalZero {
3702*042d53a7SEvalZero .sc_cmd = "gatt-discover-full",
3703*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_discover_full,
3704*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3705*042d53a7SEvalZero .help = &gatt_discover_full_help,
3706*042d53a7SEvalZero #endif
3707*042d53a7SEvalZero },
3708*042d53a7SEvalZero {
3709*042d53a7SEvalZero .sc_cmd = "gatt-find-included-services",
3710*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_find_included_services,
3711*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3712*042d53a7SEvalZero .help = &gatt_find_included_services_help,
3713*042d53a7SEvalZero #endif
3714*042d53a7SEvalZero },
3715*042d53a7SEvalZero {
3716*042d53a7SEvalZero .sc_cmd = "gatt-exchange-mtu",
3717*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_exchange_mtu,
3718*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3719*042d53a7SEvalZero .help = &gatt_exchange_mtu_help,
3720*042d53a7SEvalZero #endif
3721*042d53a7SEvalZero },
3722*042d53a7SEvalZero {
3723*042d53a7SEvalZero .sc_cmd = "gatt-read",
3724*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_read,
3725*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3726*042d53a7SEvalZero .help = &gatt_read_help,
3727*042d53a7SEvalZero #endif
3728*042d53a7SEvalZero },
3729*042d53a7SEvalZero {
3730*042d53a7SEvalZero .sc_cmd = "gatt-notify",
3731*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_notify,
3732*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3733*042d53a7SEvalZero .help = &gatt_notify_help,
3734*042d53a7SEvalZero #endif
3735*042d53a7SEvalZero },
3736*042d53a7SEvalZero {
3737*042d53a7SEvalZero .sc_cmd = "gatt-service-changed",
3738*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_service_changed,
3739*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3740*042d53a7SEvalZero .help = &gatt_service_changed_help,
3741*042d53a7SEvalZero #endif
3742*042d53a7SEvalZero },
3743*042d53a7SEvalZero {
3744*042d53a7SEvalZero .sc_cmd = "gatt-service-visibility",
3745*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_service_visibility,
3746*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3747*042d53a7SEvalZero .help = &gatt_service_visibility_help,
3748*042d53a7SEvalZero #endif
3749*042d53a7SEvalZero },
3750*042d53a7SEvalZero {
3751*042d53a7SEvalZero .sc_cmd = "gatt-show",
3752*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_show,
3753*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3754*042d53a7SEvalZero .help = &gatt_show_help,
3755*042d53a7SEvalZero #endif
3756*042d53a7SEvalZero },
3757*042d53a7SEvalZero {
3758*042d53a7SEvalZero .sc_cmd = "gatt-show-local",
3759*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_show_local,
3760*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3761*042d53a7SEvalZero .help = &gatt_show_local_help,
3762*042d53a7SEvalZero #endif
3763*042d53a7SEvalZero },
3764*042d53a7SEvalZero {
3765*042d53a7SEvalZero .sc_cmd = "gatt-write",
3766*042d53a7SEvalZero .sc_cmd_func = cmd_gatt_write,
3767*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3768*042d53a7SEvalZero .help = &gatt_write_help,
3769*042d53a7SEvalZero #endif
3770*042d53a7SEvalZero },
3771*042d53a7SEvalZero #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
3772*042d53a7SEvalZero {
3773*042d53a7SEvalZero .sc_cmd = "l2cap-update",
3774*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_update,
3775*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3776*042d53a7SEvalZero .help = &l2cap_update_help,
3777*042d53a7SEvalZero #endif
3778*042d53a7SEvalZero },
3779*042d53a7SEvalZero {
3780*042d53a7SEvalZero .sc_cmd = "l2cap-create-server",
3781*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_create_server,
3782*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3783*042d53a7SEvalZero .help = &l2cap_create_server_help,
3784*042d53a7SEvalZero #endif
3785*042d53a7SEvalZero },
3786*042d53a7SEvalZero {
3787*042d53a7SEvalZero .sc_cmd = "l2cap-connect",
3788*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_connect,
3789*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3790*042d53a7SEvalZero .help = &l2cap_connect_help,
3791*042d53a7SEvalZero #endif
3792*042d53a7SEvalZero },
3793*042d53a7SEvalZero {
3794*042d53a7SEvalZero .sc_cmd = "l2cap-disconnect",
3795*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_disconnect,
3796*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3797*042d53a7SEvalZero .help = &l2cap_disconnect_help,
3798*042d53a7SEvalZero #endif
3799*042d53a7SEvalZero },
3800*042d53a7SEvalZero {
3801*042d53a7SEvalZero .sc_cmd = "l2cap-send",
3802*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_send,
3803*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3804*042d53a7SEvalZero .help = &l2cap_send_help,
3805*042d53a7SEvalZero #endif
3806*042d53a7SEvalZero },
3807*042d53a7SEvalZero {
3808*042d53a7SEvalZero .sc_cmd = "l2cap-show-coc",
3809*042d53a7SEvalZero .sc_cmd_func = cmd_l2cap_show_coc,
3810*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3811*042d53a7SEvalZero .help = &l2cap_show_coc_help,
3812*042d53a7SEvalZero #endif
3813*042d53a7SEvalZero },
3814*042d53a7SEvalZero #endif
3815*042d53a7SEvalZero {
3816*042d53a7SEvalZero .sc_cmd = "keystore-add",
3817*042d53a7SEvalZero .sc_cmd_func = cmd_keystore_add,
3818*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3819*042d53a7SEvalZero .help = &keystore_add_help,
3820*042d53a7SEvalZero #endif
3821*042d53a7SEvalZero },
3822*042d53a7SEvalZero {
3823*042d53a7SEvalZero .sc_cmd = "keystore-del",
3824*042d53a7SEvalZero .sc_cmd_func = cmd_keystore_del,
3825*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3826*042d53a7SEvalZero .help = &keystore_del_help,
3827*042d53a7SEvalZero #endif
3828*042d53a7SEvalZero },
3829*042d53a7SEvalZero {
3830*042d53a7SEvalZero .sc_cmd = "keystore-show",
3831*042d53a7SEvalZero .sc_cmd_func = cmd_keystore_show,
3832*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3833*042d53a7SEvalZero .help = &keystore_show_help,
3834*042d53a7SEvalZero #endif
3835*042d53a7SEvalZero },
3836*042d53a7SEvalZero #if NIMBLE_BLE_SM
3837*042d53a7SEvalZero {
3838*042d53a7SEvalZero .sc_cmd = "auth-passkey",
3839*042d53a7SEvalZero .sc_cmd_func = cmd_auth_passkey,
3840*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3841*042d53a7SEvalZero .help = &auth_passkey_help,
3842*042d53a7SEvalZero #endif
3843*042d53a7SEvalZero },
3844*042d53a7SEvalZero {
3845*042d53a7SEvalZero .sc_cmd = "security-pair",
3846*042d53a7SEvalZero .sc_cmd_func = cmd_security_pair,
3847*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3848*042d53a7SEvalZero .help = &security_pair_help,
3849*042d53a7SEvalZero #endif
3850*042d53a7SEvalZero },
3851*042d53a7SEvalZero {
3852*042d53a7SEvalZero .sc_cmd = "security-unpair",
3853*042d53a7SEvalZero .sc_cmd_func = cmd_security_unpair,
3854*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3855*042d53a7SEvalZero .help = &security_unpair_help,
3856*042d53a7SEvalZero #endif
3857*042d53a7SEvalZero },
3858*042d53a7SEvalZero {
3859*042d53a7SEvalZero .sc_cmd = "security-start",
3860*042d53a7SEvalZero .sc_cmd_func = cmd_security_start,
3861*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3862*042d53a7SEvalZero .help = &security_start_help,
3863*042d53a7SEvalZero #endif
3864*042d53a7SEvalZero },
3865*042d53a7SEvalZero {
3866*042d53a7SEvalZero .sc_cmd = "security-encryption",
3867*042d53a7SEvalZero .sc_cmd_func = cmd_security_encryption,
3868*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3869*042d53a7SEvalZero .help = &security_encryption_help,
3870*042d53a7SEvalZero #endif
3871*042d53a7SEvalZero },
3872*042d53a7SEvalZero {
3873*042d53a7SEvalZero .sc_cmd = "security-set-data",
3874*042d53a7SEvalZero .sc_cmd_func = cmd_security_set_data,
3875*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3876*042d53a7SEvalZero .help = &security_set_data_help,
3877*042d53a7SEvalZero #endif
3878*042d53a7SEvalZero },
3879*042d53a7SEvalZero #endif
3880*042d53a7SEvalZero {
3881*042d53a7SEvalZero .sc_cmd = "test-tx",
3882*042d53a7SEvalZero .sc_cmd_func = cmd_test_tx,
3883*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3884*042d53a7SEvalZero .help = &test_tx_help,
3885*042d53a7SEvalZero #endif
3886*042d53a7SEvalZero },
3887*042d53a7SEvalZero {
3888*042d53a7SEvalZero .sc_cmd = "phy-set",
3889*042d53a7SEvalZero .sc_cmd_func = cmd_phy_set,
3890*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3891*042d53a7SEvalZero .help = &phy_set_help,
3892*042d53a7SEvalZero #endif
3893*042d53a7SEvalZero },
3894*042d53a7SEvalZero {
3895*042d53a7SEvalZero .sc_cmd = "phy-set-default",
3896*042d53a7SEvalZero .sc_cmd_func = cmd_phy_set_default,
3897*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3898*042d53a7SEvalZero .help = &phy_set_default_help,
3899*042d53a7SEvalZero #endif
3900*042d53a7SEvalZero },
3901*042d53a7SEvalZero {
3902*042d53a7SEvalZero .sc_cmd = "phy-read",
3903*042d53a7SEvalZero .sc_cmd_func = cmd_phy_read,
3904*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3905*042d53a7SEvalZero .help = &phy_read_help,
3906*042d53a7SEvalZero #endif
3907*042d53a7SEvalZero },
3908*042d53a7SEvalZero {
3909*042d53a7SEvalZero .sc_cmd = "host-enable",
3910*042d53a7SEvalZero .sc_cmd_func = cmd_host_enable,
3911*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3912*042d53a7SEvalZero .help = &host_enable_help,
3913*042d53a7SEvalZero #endif
3914*042d53a7SEvalZero },
3915*042d53a7SEvalZero {
3916*042d53a7SEvalZero .sc_cmd = "host-disable",
3917*042d53a7SEvalZero .sc_cmd_func = cmd_host_disable,
3918*042d53a7SEvalZero #if MYNEWT_VAL(SHELL_CMD_HELP)
3919*042d53a7SEvalZero .help = &host_disable_help,
3920*042d53a7SEvalZero #endif
3921*042d53a7SEvalZero },
3922*042d53a7SEvalZero { NULL, NULL, NULL },
3923*042d53a7SEvalZero };
3924*042d53a7SEvalZero
3925*042d53a7SEvalZero
3926*042d53a7SEvalZero void
cmd_init(void)3927*042d53a7SEvalZero cmd_init(void)
3928*042d53a7SEvalZero {
3929*042d53a7SEvalZero shell_register(BTSHELL_MODULE, btshell_commands);
3930*042d53a7SEvalZero shell_register_default_module(BTSHELL_MODULE);
3931*042d53a7SEvalZero }
3932