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 <string.h>
22*042d53a7SEvalZero
23*042d53a7SEvalZero /* BLE */
24*042d53a7SEvalZero #include "nimble/ble.h"
25*042d53a7SEvalZero #include "nimble/ble_hci_trans.h"
26*042d53a7SEvalZero #include "nimble/hci_common.h"
27*042d53a7SEvalZero #include "host/ble_hs.h"
28*042d53a7SEvalZero
29*042d53a7SEvalZero #include "nimble/nimble_npl.h"
30*042d53a7SEvalZero #include "nimble/npl_shell.h"
31*042d53a7SEvalZero
32*042d53a7SEvalZero /* XXX: An app should not include private headers from a library. The bletest
33*042d53a7SEvalZero * app uses some of nimble's internal details for logging.
34*042d53a7SEvalZero */
35*042d53a7SEvalZero #include "ble_hs_priv.h"
36*042d53a7SEvalZero #include "bletest_priv.h"
37*042d53a7SEvalZero
38*042d53a7SEvalZero #include <rtthread.h>
39*042d53a7SEvalZero
40*042d53a7SEvalZero #define BLETEST_TASK_PRIO 5
41*042d53a7SEvalZero
42*042d53a7SEvalZero /* For LED toggling */
43*042d53a7SEvalZero int g_led_pin;
44*042d53a7SEvalZero
45*042d53a7SEvalZero /* A buffer for host advertising data */
46*042d53a7SEvalZero uint8_t g_host_adv_data[BLE_HCI_MAX_ADV_DATA_LEN];
47*042d53a7SEvalZero uint8_t g_host_adv_len;
48*042d53a7SEvalZero static uint8_t _g_dev_addr[BLE_DEV_ADDR_LEN];
49*042d53a7SEvalZero
50*042d53a7SEvalZero /* Some application configurations */
51*042d53a7SEvalZero #define BLETEST_ROLE_NONE (0)
52*042d53a7SEvalZero #define BLETEST_ROLE_ADVERTISER (1)
53*042d53a7SEvalZero #define BLETEST_ROLE_SCANNER (2)
54*042d53a7SEvalZero #define BLETEST_ROLE_INITIATOR (3)
55*042d53a7SEvalZero
56*042d53a7SEvalZero #define MYNEWT_VAL_BLETEST_ROLE BLETEST_ROLE_ADVERTISER
57*042d53a7SEvalZero
58*042d53a7SEvalZero #if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_ADVERTISER
59*042d53a7SEvalZero #define BLETEST_CFG_ROLE BLETEST_ROLE_ADVERTISER
60*042d53a7SEvalZero #endif
61*042d53a7SEvalZero #if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_SCANNER
62*042d53a7SEvalZero #define BLETEST_CFG_ROLE BLETEST_ROLE_SCANNER
63*042d53a7SEvalZero #endif
64*042d53a7SEvalZero #if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_INITIATOR
65*042d53a7SEvalZero #define BLETEST_CFG_ROLE BLETEST_ROLE_INITIATOR
66*042d53a7SEvalZero #endif
67*042d53a7SEvalZero
68*042d53a7SEvalZero #ifndef BLETEST_CFG_ROLE
69*042d53a7SEvalZero #error "No role defined! Must define a valid role in syscfg.yml in apps/bletest"
70*042d53a7SEvalZero #endif
71*042d53a7SEvalZero
72*042d53a7SEvalZero /* Advertiser config */
73*042d53a7SEvalZero #define BLETEST_CFG_ADV_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
74*042d53a7SEvalZero #define BLETEST_CFG_ADV_PEER_ADDR_TYPE (BLE_HCI_ADV_PEER_ADDR_PUBLIC)
75*042d53a7SEvalZero #define BLETEST_CFG_ADV_ITVL (60000 / BLE_HCI_ADV_ITVL)
76*042d53a7SEvalZero #define BLETEST_CFG_ADV_TYPE BLE_HCI_ADV_TYPE_ADV_IND
77*042d53a7SEvalZero #define BLETEST_CFG_ADV_FILT_POLICY (BLE_HCI_ADV_FILT_NONE)
78*042d53a7SEvalZero #define BLETEST_CFG_ADV_ADDR_RES_EN (0)
79*042d53a7SEvalZero
80*042d53a7SEvalZero /* Multi-adv config */
81*042d53a7SEvalZero /*
82*042d53a7SEvalZero * Number of advertising instances to start up, not including the default
83*042d53a7SEvalZero * instance. The default instance is used to connect. If this number is greater
84*042d53a7SEvalZero * than the number of available advertising instances, we only use the number
85*042d53a7SEvalZero * of available advertising instances (defined by the configuration setting:
86*042d53a7SEvalZero * BLE_MULTI_ADV_INSTANCES.
87*042d53a7SEvalZero */
88*042d53a7SEvalZero #define BLETEST_CFG_ADV_TEST_INSTANCES (8)
89*042d53a7SEvalZero
90*042d53a7SEvalZero struct bletest_multi_adv_interval
91*042d53a7SEvalZero {
92*042d53a7SEvalZero uint8_t adv_type;
93*042d53a7SEvalZero /*
94*042d53a7SEvalZero * Note: if own addr type greater than 1, we use own addr field; otherwise
95*042d53a7SEvalZero * we use the set multi random address call to set the random address
96*042d53a7SEvalZero */
97*042d53a7SEvalZero uint8_t adv_own_addr_type;
98*042d53a7SEvalZero uint16_t adv_itvl;
99*042d53a7SEvalZero };
100*042d53a7SEvalZero
101*042d53a7SEvalZero /*
102*042d53a7SEvalZero * NOTE: currently, these are all NONCONN_IND. Thus, must be 100 msecs or
103*042d53a7SEvalZero * greater
104*042d53a7SEvalZero */
105*042d53a7SEvalZero const struct bletest_multi_adv_interval
106*042d53a7SEvalZero bletest_multi_adv_instances[BLETEST_CFG_ADV_TEST_INSTANCES] = {
107*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
108*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_PUBLIC,
109*042d53a7SEvalZero (100000 / BLE_HCI_ADV_ITVL)},
110*042d53a7SEvalZero
111*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
112*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_RANDOM,
113*042d53a7SEvalZero (110000 / BLE_HCI_ADV_ITVL)},
114*042d53a7SEvalZero
115*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
116*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_RANDOM,
117*042d53a7SEvalZero (120000 / BLE_HCI_ADV_ITVL)},
118*042d53a7SEvalZero
119*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
120*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_PUBLIC,
121*042d53a7SEvalZero (130000 / BLE_HCI_ADV_ITVL)},
122*042d53a7SEvalZero
123*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
124*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_MAX + 1,
125*042d53a7SEvalZero (140000 / BLE_HCI_ADV_ITVL)},
126*042d53a7SEvalZero
127*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
128*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_MAX + 1,
129*042d53a7SEvalZero (150000 / BLE_HCI_ADV_ITVL)},
130*042d53a7SEvalZero
131*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
132*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_PUBLIC,
133*042d53a7SEvalZero (160000 / BLE_HCI_ADV_ITVL)},
134*042d53a7SEvalZero
135*042d53a7SEvalZero {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
136*042d53a7SEvalZero BLE_HCI_ADV_OWN_ADDR_PUBLIC,
137*042d53a7SEvalZero (170000 / BLE_HCI_ADV_ITVL)}
138*042d53a7SEvalZero };
139*042d53a7SEvalZero
140*042d53a7SEvalZero /*
141*042d53a7SEvalZero * Determines if own address contains random address or set through the
142*042d53a7SEvalZero * multi-adv set random address command
143*042d53a7SEvalZero */
144*042d53a7SEvalZero #define BLETEST_CFG_MULTI_ADV_RANDOM_OWN (0)
145*042d53a7SEvalZero
146*042d53a7SEvalZero /* Scan config */
147*042d53a7SEvalZero #define BLETEST_CFG_SCAN_ITVL (700000 / BLE_HCI_SCAN_ITVL)
148*042d53a7SEvalZero #define BLETEST_CFG_SCAN_WINDOW (700000 / BLE_HCI_SCAN_ITVL)
149*042d53a7SEvalZero #define BLETEST_CFG_SCAN_TYPE (BLE_HCI_SCAN_TYPE_PASSIVE)
150*042d53a7SEvalZero #define BLETEST_CFG_SCAN_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
151*042d53a7SEvalZero #define BLETEST_CFG_SCAN_FILT_POLICY (BLE_HCI_SCAN_FILT_NO_WL)
152*042d53a7SEvalZero #define BLETEST_CFG_FILT_DUP_ADV (1)
153*042d53a7SEvalZero
154*042d53a7SEvalZero /* Connection config */
155*042d53a7SEvalZero #define BLETEST_CFG_CONN_ITVL (128) /* in 1.25 msec increments */
156*042d53a7SEvalZero #define BLETEST_CFG_SLAVE_LATENCY (0)
157*042d53a7SEvalZero #define BLETEST_CFG_INIT_FILTER_POLICY (BLE_HCI_CONN_FILT_NO_WL)
158*042d53a7SEvalZero #define BLETEST_CFG_CONN_SPVN_TMO (1000) /* 10 msec increments */
159*042d53a7SEvalZero #define BLETEST_CFG_MIN_CE_LEN (6)
160*042d53a7SEvalZero #define BLETEST_CFG_MAX_CE_LEN (BLETEST_CFG_CONN_ITVL)
161*042d53a7SEvalZero #define BLETEST_CFG_CONN_PEER_ADDR_TYPE (BLE_HCI_CONN_PEER_ADDR_PUBLIC)
162*042d53a7SEvalZero #define BLETEST_CFG_CONN_OWN_ADDR_TYPE (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
163*042d53a7SEvalZero #define BLETEST_CFG_CONCURRENT_CONNS (1)
164*042d53a7SEvalZero
165*042d53a7SEvalZero /* Test packet config */
166*042d53a7SEvalZero #define BLETEST_CFG_RAND_PKT_SIZE (1)
167*042d53a7SEvalZero #define BLETEST_CFG_SUGG_DEF_TXOCTETS (251)
168*042d53a7SEvalZero #define BLETEST_CFG_SUGG_DEF_TXTIME (2000)
169*042d53a7SEvalZero
170*042d53a7SEvalZero /* Test configurations. One of these should be set to 1 */
171*042d53a7SEvalZero #if !defined(BLETEST_CONCURRENT_CONN_TEST) && !defined(BLETEST_THROUGHPUT_TEST)
172*042d53a7SEvalZero #define BLETEST_CONCURRENT_CONN_TEST (1)
173*042d53a7SEvalZero #endif
174*042d53a7SEvalZero
175*042d53a7SEvalZero /* BLETEST variables */
176*042d53a7SEvalZero #undef BLETEST_ADV_PKT_NUM
177*042d53a7SEvalZero #define BLETEST_MAX_PKT_SIZE (247)
178*042d53a7SEvalZero #define BLETEST_PKT_SIZE (247)
179*042d53a7SEvalZero #define BLETEST_STACK_SIZE (256)
180*042d53a7SEvalZero uint32_t g_next_os_time;
181*042d53a7SEvalZero int g_bletest_state;
182*042d53a7SEvalZero struct ble_npl_eventq g_bletest_evq;
183*042d53a7SEvalZero struct ble_npl_callout g_bletest_timer;
184*042d53a7SEvalZero //struct ble_npl_task bletest_task;
185*042d53a7SEvalZero //bssnz_t os_stack_t bletest_stack[BLETEST_STACK_SIZE];
186*042d53a7SEvalZero uint32_t g_bletest_conn_end;
187*042d53a7SEvalZero int g_bletest_start_update;
188*042d53a7SEvalZero uint32_t g_bletest_conn_upd_time;
189*042d53a7SEvalZero uint8_t g_bletest_current_conns;
190*042d53a7SEvalZero uint8_t g_bletest_cur_peer_addr[BLE_DEV_ADDR_LEN];
191*042d53a7SEvalZero uint8_t g_last_handle_used;
192*042d53a7SEvalZero uint8_t g_bletest_led_state;
193*042d53a7SEvalZero uint32_t g_bletest_led_rate;
194*042d53a7SEvalZero uint32_t g_bletest_next_led_time;
195*042d53a7SEvalZero uint16_t g_bletest_handle;
196*042d53a7SEvalZero uint16_t g_bletest_completed_pkts;
197*042d53a7SEvalZero uint16_t g_bletest_outstanding_pkts;
198*042d53a7SEvalZero uint16_t g_bletest_ltk_reply_handle;
199*042d53a7SEvalZero uint32_t g_bletest_hw_id[4];
200*042d53a7SEvalZero struct hci_create_conn g_cc;
201*042d53a7SEvalZero
202*042d53a7SEvalZero /* --- For LE encryption testing --- */
203*042d53a7SEvalZero /* Key: 0x4C68384139F574D836BCF34E9DFB01BF */
204*042d53a7SEvalZero const uint8_t g_ble_ll_encrypt_test_key[16] =
205*042d53a7SEvalZero {
206*042d53a7SEvalZero 0x4c, 0x68, 0x38, 0x41, 0x39, 0xf5, 0x74, 0xd8,
207*042d53a7SEvalZero 0x36, 0xbc, 0xf3, 0x4e, 0x9d, 0xfb, 0x01, 0xbf
208*042d53a7SEvalZero };
209*042d53a7SEvalZero
210*042d53a7SEvalZero /* Plaint text: 0x0213243546576879acbdcedfe0f10213 */
211*042d53a7SEvalZero const uint8_t g_ble_ll_encrypt_test_plain_text[16] =
212*042d53a7SEvalZero {
213*042d53a7SEvalZero 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
214*042d53a7SEvalZero 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1, 0x02, 0x13
215*042d53a7SEvalZero };
216*042d53a7SEvalZero
217*042d53a7SEvalZero /* Encrypted data: 0x99ad1b5226a37e3e058e3b8e27c2c666 */
218*042d53a7SEvalZero const uint8_t g_ble_ll_encrypt_test_encrypted_data[16] =
219*042d53a7SEvalZero {
220*042d53a7SEvalZero 0x99, 0xad, 0x1b, 0x52, 0x26, 0xa3, 0x7e, 0x3e,
221*042d53a7SEvalZero 0x05, 0x8e, 0x3b, 0x8e, 0x27, 0xc2, 0xc6, 0x66
222*042d53a7SEvalZero };
223*042d53a7SEvalZero
224*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
225*042d53a7SEvalZero uint8_t g_bletest_adv_irk[16] = {
226*042d53a7SEvalZero 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05,
227*042d53a7SEvalZero 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b
228*042d53a7SEvalZero };
229*042d53a7SEvalZero
230*042d53a7SEvalZero uint8_t g_bletest_init_irk[16] = {
231*042d53a7SEvalZero 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
232*042d53a7SEvalZero 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
233*042d53a7SEvalZero };
234*042d53a7SEvalZero #endif
235*042d53a7SEvalZero
236*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
237*042d53a7SEvalZero /* LTK 0x4C68384139F574D836BCF34E9DFB01BF */
238*042d53a7SEvalZero const uint8_t g_bletest_LTK[16] =
239*042d53a7SEvalZero {
240*042d53a7SEvalZero 0x4C,0x68,0x38,0x41,0x39,0xF5,0x74,0xD8,
241*042d53a7SEvalZero 0x36,0xBC,0xF3,0x4E,0x9D,0xFB,0x01,0xBF
242*042d53a7SEvalZero };
243*042d53a7SEvalZero uint16_t g_bletest_EDIV = 0x2474;
244*042d53a7SEvalZero uint64_t g_bletest_RAND = 0xABCDEF1234567890;
245*042d53a7SEvalZero uint64_t g_bletest_SKDm = 0xACBDCEDFE0F10213;
246*042d53a7SEvalZero uint64_t g_bletest_SKDs = 0x0213243546576879;
247*042d53a7SEvalZero uint32_t g_bletest_IVm = 0xBADCAB24;
248*042d53a7SEvalZero uint32_t g_bletest_IVs = 0xDEAFBABE;
249*042d53a7SEvalZero #endif
250*042d53a7SEvalZero
251*042d53a7SEvalZero #if (BLETEST_THROUGHPUT_TEST == 1)
252*042d53a7SEvalZero void
bletest_completed_pkt(uint16_t handle)253*042d53a7SEvalZero bletest_completed_pkt(uint16_t handle)
254*042d53a7SEvalZero {
255*042d53a7SEvalZero os_sr_t sr;
256*042d53a7SEvalZero
257*042d53a7SEvalZero OS_ENTER_CRITICAL(sr);
258*042d53a7SEvalZero if (handle == g_bletest_handle) {
259*042d53a7SEvalZero ++g_bletest_completed_pkts;
260*042d53a7SEvalZero }
261*042d53a7SEvalZero OS_EXIT_CRITICAL(sr);
262*042d53a7SEvalZero }
263*042d53a7SEvalZero #endif
264*042d53a7SEvalZero
265*042d53a7SEvalZero #ifdef BLETEST_ADV_PKT_NUM
266*042d53a7SEvalZero void
bletest_inc_adv_pkt_num(void)267*042d53a7SEvalZero bletest_inc_adv_pkt_num(void)
268*042d53a7SEvalZero {
269*042d53a7SEvalZero int rc;
270*042d53a7SEvalZero uint8_t *dptr;
271*042d53a7SEvalZero uint8_t digit;
272*042d53a7SEvalZero
273*042d53a7SEvalZero if (g_host_adv_len != 0) {
274*042d53a7SEvalZero dptr = &g_host_adv_data[18];
275*042d53a7SEvalZero while (dptr >= &g_host_adv_data[13]) {
276*042d53a7SEvalZero digit = *dptr;
277*042d53a7SEvalZero ++digit;
278*042d53a7SEvalZero if (digit == 58) {
279*042d53a7SEvalZero digit = 48;
280*042d53a7SEvalZero *dptr = digit;
281*042d53a7SEvalZero --dptr;
282*042d53a7SEvalZero } else {
283*042d53a7SEvalZero *dptr = digit;
284*042d53a7SEvalZero break;
285*042d53a7SEvalZero }
286*042d53a7SEvalZero }
287*042d53a7SEvalZero
288*042d53a7SEvalZero rc = bletest_hci_le_set_adv_data(g_host_adv_data, g_host_adv_len);
289*042d53a7SEvalZero assert(rc == 0);
290*042d53a7SEvalZero }
291*042d53a7SEvalZero }
292*042d53a7SEvalZero #endif
293*042d53a7SEvalZero
294*042d53a7SEvalZero /**
295*042d53a7SEvalZero * Sets the advertising data to be sent in advertising pdu's which contain
296*042d53a7SEvalZero * advertising data.
297*042d53a7SEvalZero *
298*042d53a7SEvalZero * @param dptr
299*042d53a7SEvalZero * @return uint8_t
300*042d53a7SEvalZero */
301*042d53a7SEvalZero uint8_t
bletest_set_adv_data(uint8_t * dptr,uint8_t * addr)302*042d53a7SEvalZero bletest_set_adv_data(uint8_t *dptr, uint8_t *addr)
303*042d53a7SEvalZero {
304*042d53a7SEvalZero uint8_t len;
305*042d53a7SEvalZero
306*042d53a7SEvalZero /* Place flags in first */
307*042d53a7SEvalZero dptr[0] = 0x02;
308*042d53a7SEvalZero dptr[1] = 0x01; /* Flags identifier */
309*042d53a7SEvalZero dptr[2] = 0x06;
310*042d53a7SEvalZero dptr += 3;
311*042d53a7SEvalZero len = 3;
312*042d53a7SEvalZero
313*042d53a7SEvalZero /* Add HID service */
314*042d53a7SEvalZero dptr[0] = 0x03;
315*042d53a7SEvalZero dptr[1] = 0x03;
316*042d53a7SEvalZero dptr[2] = 0x12;
317*042d53a7SEvalZero dptr[3] = 0x18;
318*042d53a7SEvalZero dptr += 4;
319*042d53a7SEvalZero len += 4;
320*042d53a7SEvalZero
321*042d53a7SEvalZero /* Add local name */
322*042d53a7SEvalZero dptr[0] = 12; /* Length of this data, not including the length */
323*042d53a7SEvalZero dptr[1] = 0x09;
324*042d53a7SEvalZero dptr[2] = 'r';
325*042d53a7SEvalZero dptr[3] = 'u';
326*042d53a7SEvalZero dptr[4] = 'n';
327*042d53a7SEvalZero dptr[5] = 't';
328*042d53a7SEvalZero dptr[6] = 'i';
329*042d53a7SEvalZero dptr[7] = 'm';
330*042d53a7SEvalZero dptr[8] = 'e';
331*042d53a7SEvalZero dptr[9] = '-';
332*042d53a7SEvalZero dptr[10] = '0';
333*042d53a7SEvalZero dptr[11] = '0';
334*042d53a7SEvalZero dptr[12] = '7';
335*042d53a7SEvalZero dptr += 13;
336*042d53a7SEvalZero len += 13;
337*042d53a7SEvalZero
338*042d53a7SEvalZero /* Add local device address */
339*042d53a7SEvalZero dptr[0] = 0x08;
340*042d53a7SEvalZero dptr[1] = 0x1B;
341*042d53a7SEvalZero dptr[2] = 0x00;
342*042d53a7SEvalZero memcpy(dptr + 3, addr, BLE_DEV_ADDR_LEN);
343*042d53a7SEvalZero len += 9;
344*042d53a7SEvalZero
345*042d53a7SEvalZero g_host_adv_len = len;
346*042d53a7SEvalZero
347*042d53a7SEvalZero return len;
348*042d53a7SEvalZero }
349*042d53a7SEvalZero
350*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
351*042d53a7SEvalZero #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
352*042d53a7SEvalZero void
bletest_init_adv_instances(void)353*042d53a7SEvalZero bletest_init_adv_instances(void)
354*042d53a7SEvalZero {
355*042d53a7SEvalZero uint8_t i;
356*042d53a7SEvalZero int rc;
357*042d53a7SEvalZero uint8_t *addr;
358*042d53a7SEvalZero uint8_t adv_len;
359*042d53a7SEvalZero uint8_t inst_allowed;
360*042d53a7SEvalZero uint8_t rand_addr[BLE_DEV_ADDR_LEN];
361*042d53a7SEvalZero struct hci_multi_adv_params adv;
362*042d53a7SEvalZero
363*042d53a7SEvalZero inst_allowed = MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES);
364*042d53a7SEvalZero if (inst_allowed > BLETEST_CFG_ADV_TEST_INSTANCES) {
365*042d53a7SEvalZero inst_allowed = BLETEST_CFG_ADV_TEST_INSTANCES;
366*042d53a7SEvalZero }
367*042d53a7SEvalZero
368*042d53a7SEvalZero /* Start up all the instances */
369*042d53a7SEvalZero for (i = 1; i <= inst_allowed; ++i) {
370*042d53a7SEvalZero memset(&adv, 0, sizeof(struct hci_multi_adv_params));
371*042d53a7SEvalZero
372*042d53a7SEvalZero adv.own_addr_type = bletest_multi_adv_instances[i-1].adv_own_addr_type;
373*042d53a7SEvalZero if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
374*042d53a7SEvalZero addr = _g_dev_addr;
375*042d53a7SEvalZero } else {
376*042d53a7SEvalZero memcpy(rand_addr, _g_dev_addr, BLE_DEV_ADDR_LEN);
377*042d53a7SEvalZero rand_addr[5] |= 0xc0;
378*042d53a7SEvalZero rand_addr[0] = i;
379*042d53a7SEvalZero /*
380*042d53a7SEvalZero * NOTE: we overload own address type with a special case
381*042d53a7SEvalZero * to denote if we use own address or call to set multi random
382*042d53a7SEvalZero * address.
383*042d53a7SEvalZero */
384*042d53a7SEvalZero if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
385*042d53a7SEvalZero rc = bletest_hci_le_set_multi_rand_addr(rand_addr, i);
386*042d53a7SEvalZero assert(rc == 0);
387*042d53a7SEvalZero addr = rand_addr;
388*042d53a7SEvalZero } else {
389*042d53a7SEvalZero adv.own_addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM;
390*042d53a7SEvalZero addr = rand_addr;
391*042d53a7SEvalZero memcpy(adv.own_addr, addr, BLE_DEV_ADDR_LEN);
392*042d53a7SEvalZero }
393*042d53a7SEvalZero }
394*042d53a7SEvalZero
395*042d53a7SEvalZero adv.adv_type = bletest_multi_adv_instances[i - 1].adv_type;
396*042d53a7SEvalZero adv.adv_channel_map = 0x07;
397*042d53a7SEvalZero adv.adv_filter_policy = BLE_HCI_ADV_FILT_NONE;
398*042d53a7SEvalZero adv.peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC;
399*042d53a7SEvalZero adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
400*042d53a7SEvalZero
401*042d53a7SEvalZero adv.adv_itvl_min = bletest_multi_adv_instances[i - 1].adv_itvl;
402*042d53a7SEvalZero adv.adv_itvl_max = bletest_multi_adv_instances[i - 1].adv_itvl;
403*042d53a7SEvalZero adv.adv_tx_pwr = -1 * i;
404*042d53a7SEvalZero
405*042d53a7SEvalZero /* Set the advertising parameters */
406*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_params(&adv, i);
407*042d53a7SEvalZero assert(rc == 0);
408*042d53a7SEvalZero
409*042d53a7SEvalZero /* Set advertising data */
410*042d53a7SEvalZero if (adv_len != 0) {
411*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_data(&g_host_adv_data[0], adv_len,
412*042d53a7SEvalZero i);
413*042d53a7SEvalZero assert(rc == 0);
414*042d53a7SEvalZero
415*042d53a7SEvalZero /* Set scan response data */
416*042d53a7SEvalZero rc = bletest_hci_le_set_multi_scan_rsp_data(&g_host_adv_data[0],
417*042d53a7SEvalZero adv_len, i);
418*042d53a7SEvalZero assert(rc == 0);
419*042d53a7SEvalZero }
420*042d53a7SEvalZero
421*042d53a7SEvalZero /* Set the advertising parameters */
422*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_enable(1, i);
423*042d53a7SEvalZero assert(rc == 0);
424*042d53a7SEvalZero }
425*042d53a7SEvalZero }
426*042d53a7SEvalZero
427*042d53a7SEvalZero void
bletest_init_advertising(uint8_t instance,int8_t txpwr)428*042d53a7SEvalZero bletest_init_advertising(uint8_t instance, int8_t txpwr)
429*042d53a7SEvalZero {
430*042d53a7SEvalZero int rc;
431*042d53a7SEvalZero int set_peer_addr;
432*042d53a7SEvalZero uint8_t adv_len;
433*042d53a7SEvalZero uint8_t *addr;
434*042d53a7SEvalZero uint8_t rand_addr[BLE_DEV_ADDR_LEN];
435*042d53a7SEvalZero struct hci_multi_adv_params adv;
436*042d53a7SEvalZero
437*042d53a7SEvalZero /* Make sure it is a valid instance */
438*042d53a7SEvalZero assert(instance < BLE_LL_ADV_INSTANCES);
439*042d53a7SEvalZero
440*042d53a7SEvalZero /* Just zero out advertising */
441*042d53a7SEvalZero set_peer_addr = 0;
442*042d53a7SEvalZero memset(&adv, 0, sizeof(struct hci_multi_adv_params));
443*042d53a7SEvalZero
444*042d53a7SEvalZero /* If we are using a random address, we need to set it */
445*042d53a7SEvalZero adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE;
446*042d53a7SEvalZero if (adv.own_addr_type & 1) {
447*042d53a7SEvalZero memcpy(rand_addr, _g_dev_addr, BLE_DEV_ADDR_LEN);
448*042d53a7SEvalZero rand_addr[5] |= 0xc0;
449*042d53a7SEvalZero if (BLETEST_CFG_MULTI_ADV_RANDOM_OWN == 1) {
450*042d53a7SEvalZero addr = rand_addr;
451*042d53a7SEvalZero memcpy(adv.own_addr, addr, BLE_DEV_ADDR_LEN);
452*042d53a7SEvalZero } else {
453*042d53a7SEvalZero rc = bletest_hci_le_set_multi_rand_addr(rand_addr, instance);
454*042d53a7SEvalZero assert(rc == 0);
455*042d53a7SEvalZero addr = rand_addr;
456*042d53a7SEvalZero }
457*042d53a7SEvalZero } else {
458*042d53a7SEvalZero addr = _g_dev_addr;
459*042d53a7SEvalZero }
460*042d53a7SEvalZero
461*042d53a7SEvalZero /* Set advertising parameters */
462*042d53a7SEvalZero adv.adv_type = BLETEST_CFG_ADV_TYPE;
463*042d53a7SEvalZero adv.adv_channel_map = 0x07;
464*042d53a7SEvalZero adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY;
465*042d53a7SEvalZero if ((adv.adv_filter_policy & 1) || (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
466*042d53a7SEvalZero set_peer_addr = 1;
467*042d53a7SEvalZero }
468*042d53a7SEvalZero adv.peer_addr_type = BLETEST_CFG_ADV_PEER_ADDR_TYPE;
469*042d53a7SEvalZero if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
470*042d53a7SEvalZero (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
471*042d53a7SEvalZero set_peer_addr = 1;
472*042d53a7SEvalZero adv_len = 0;
473*042d53a7SEvalZero } else {
474*042d53a7SEvalZero adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
475*042d53a7SEvalZero }
476*042d53a7SEvalZero
477*042d53a7SEvalZero /* Not allowed for multi-adv command */
478*042d53a7SEvalZero if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
479*042d53a7SEvalZero assert(0);
480*042d53a7SEvalZero }
481*042d53a7SEvalZero
482*042d53a7SEvalZero if (set_peer_addr) {
483*042d53a7SEvalZero memcpy(adv.peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
484*042d53a7SEvalZero if (adv.peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) {
485*042d53a7SEvalZero adv.peer_addr[5] |= 0xc0;
486*042d53a7SEvalZero }
487*042d53a7SEvalZero }
488*042d53a7SEvalZero
489*042d53a7SEvalZero console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
490*042d53a7SEvalZero adv.peer_addr[0], adv.peer_addr[1], adv.peer_addr[2],
491*042d53a7SEvalZero adv.peer_addr[3], adv.peer_addr[4], adv.peer_addr[5]);
492*042d53a7SEvalZero
493*042d53a7SEvalZero if (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
494*042d53a7SEvalZero adv.adv_itvl_min = 0;
495*042d53a7SEvalZero adv.adv_itvl_max = 0;
496*042d53a7SEvalZero } else {
497*042d53a7SEvalZero adv.adv_itvl_min = BLETEST_CFG_ADV_ITVL;
498*042d53a7SEvalZero adv.adv_itvl_max = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
499*042d53a7SEvalZero }
500*042d53a7SEvalZero
501*042d53a7SEvalZero adv.adv_tx_pwr = txpwr;
502*042d53a7SEvalZero
503*042d53a7SEvalZero /* Set the advertising parameters */
504*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_params(&adv, instance);
505*042d53a7SEvalZero assert(rc == 0);
506*042d53a7SEvalZero
507*042d53a7SEvalZero /* Set advertising data */
508*042d53a7SEvalZero if (adv_len != 0) {
509*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_data(&g_host_adv_data[0], adv_len,
510*042d53a7SEvalZero instance);
511*042d53a7SEvalZero assert(rc == 0);
512*042d53a7SEvalZero
513*042d53a7SEvalZero /* Set scan response data */
514*042d53a7SEvalZero rc = bletest_hci_le_set_multi_scan_rsp_data(&g_host_adv_data[0],adv_len,
515*042d53a7SEvalZero instance);
516*042d53a7SEvalZero assert(rc == 0);
517*042d53a7SEvalZero }
518*042d53a7SEvalZero }
519*042d53a7SEvalZero #else
520*042d53a7SEvalZero void
bletest_init_advertising(void)521*042d53a7SEvalZero bletest_init_advertising(void)
522*042d53a7SEvalZero {
523*042d53a7SEvalZero int rc;
524*042d53a7SEvalZero int set_peer_addr;
525*042d53a7SEvalZero uint8_t adv_len;
526*042d53a7SEvalZero uint8_t *addr;
527*042d53a7SEvalZero uint8_t rand_addr[BLE_DEV_ADDR_LEN];
528*042d53a7SEvalZero struct hci_adv_params adv;
529*042d53a7SEvalZero
530*042d53a7SEvalZero /* Just zero out advertising */
531*042d53a7SEvalZero set_peer_addr = 0;
532*042d53a7SEvalZero memset(&adv, 0, sizeof(struct hci_adv_params));
533*042d53a7SEvalZero
534*042d53a7SEvalZero /* If we are using a random address, we need to set it */
535*042d53a7SEvalZero adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE;
536*042d53a7SEvalZero if (adv.own_addr_type & 1) {
537*042d53a7SEvalZero memcpy(rand_addr, _g_dev_addr, BLE_DEV_ADDR_LEN);
538*042d53a7SEvalZero rand_addr[5] |= 0xc0;
539*042d53a7SEvalZero rc = bletest_hci_le_set_rand_addr(rand_addr);
540*042d53a7SEvalZero assert(rc == 0);
541*042d53a7SEvalZero addr = rand_addr;
542*042d53a7SEvalZero } else {
543*042d53a7SEvalZero addr = _g_dev_addr;
544*042d53a7SEvalZero }
545*042d53a7SEvalZero
546*042d53a7SEvalZero /* Set advertising parameters */
547*042d53a7SEvalZero adv.adv_type = BLETEST_CFG_ADV_TYPE;
548*042d53a7SEvalZero adv.adv_channel_map = 0x07;
549*042d53a7SEvalZero adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY;
550*042d53a7SEvalZero if ((adv.adv_filter_policy & 1) || (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
551*042d53a7SEvalZero set_peer_addr = 1;
552*042d53a7SEvalZero }
553*042d53a7SEvalZero adv.peer_addr_type = BLETEST_CFG_ADV_PEER_ADDR_TYPE;
554*042d53a7SEvalZero if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
555*042d53a7SEvalZero (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
556*042d53a7SEvalZero set_peer_addr = 1;
557*042d53a7SEvalZero adv_len = 0;
558*042d53a7SEvalZero } else {
559*042d53a7SEvalZero adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
560*042d53a7SEvalZero }
561*042d53a7SEvalZero
562*042d53a7SEvalZero if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
563*042d53a7SEvalZero set_peer_addr = 1;
564*042d53a7SEvalZero }
565*042d53a7SEvalZero
566*042d53a7SEvalZero if (set_peer_addr) {
567*042d53a7SEvalZero memcpy(adv.peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
568*042d53a7SEvalZero if (adv.peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) {
569*042d53a7SEvalZero adv.peer_addr[5] |= 0xc0;
570*042d53a7SEvalZero }
571*042d53a7SEvalZero }
572*042d53a7SEvalZero
573*042d53a7SEvalZero console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
574*042d53a7SEvalZero adv.peer_addr[0], adv.peer_addr[1], adv.peer_addr[2],
575*042d53a7SEvalZero adv.peer_addr[3], adv.peer_addr[4], adv.peer_addr[5]);
576*042d53a7SEvalZero
577*042d53a7SEvalZero if (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
578*042d53a7SEvalZero adv.adv_itvl_min = 0;
579*042d53a7SEvalZero adv.adv_itvl_max = 0;
580*042d53a7SEvalZero } else {
581*042d53a7SEvalZero adv.adv_itvl_min = BLETEST_CFG_ADV_ITVL;
582*042d53a7SEvalZero adv.adv_itvl_max = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
583*042d53a7SEvalZero }
584*042d53a7SEvalZero
585*042d53a7SEvalZero /* Set the advertising parameters */
586*042d53a7SEvalZero rc = bletest_hci_le_set_adv_params(&adv);
587*042d53a7SEvalZero assert(rc == 0);
588*042d53a7SEvalZero
589*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
590*042d53a7SEvalZero if ((adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) ||
591*042d53a7SEvalZero (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
592*042d53a7SEvalZero rc = bletest_hci_le_add_resolv_list(g_bletest_adv_irk,
593*042d53a7SEvalZero g_bletest_init_irk,
594*042d53a7SEvalZero adv.peer_addr,
595*042d53a7SEvalZero adv.peer_addr_type);
596*042d53a7SEvalZero assert(rc == 0);
597*042d53a7SEvalZero
598*042d53a7SEvalZero rc = bletest_hci_le_enable_resolv_list(1);
599*042d53a7SEvalZero assert(rc == 0);
600*042d53a7SEvalZero }
601*042d53a7SEvalZero #endif
602*042d53a7SEvalZero
603*042d53a7SEvalZero /* Set advertising data */
604*042d53a7SEvalZero if (adv_len != 0) {
605*042d53a7SEvalZero rc = bletest_hci_le_set_adv_data(&g_host_adv_data[0], adv_len);
606*042d53a7SEvalZero assert(rc == 0);
607*042d53a7SEvalZero
608*042d53a7SEvalZero /* Set scan response data */
609*042d53a7SEvalZero rc = bletest_hci_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
610*042d53a7SEvalZero assert(rc == 0);
611*042d53a7SEvalZero }
612*042d53a7SEvalZero }
613*042d53a7SEvalZero #endif /* MULTI_ADV SUPPORT */
614*042d53a7SEvalZero #endif /* BLETEST_ROLE_ADVERTISER */
615*042d53a7SEvalZero
616*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
617*042d53a7SEvalZero void
bletest_init_scanner(void)618*042d53a7SEvalZero bletest_init_scanner(void)
619*042d53a7SEvalZero {
620*042d53a7SEvalZero int rc;
621*042d53a7SEvalZero uint8_t own_addr_type;
622*042d53a7SEvalZero uint8_t buf[BLE_HCI_SET_SCAN_PARAM_LEN];
623*042d53a7SEvalZero uint8_t add_whitelist;
624*042d53a7SEvalZero
625*042d53a7SEvalZero own_addr_type = BLETEST_CFG_SCAN_OWN_ADDR_TYPE;
626*042d53a7SEvalZero rc = ble_hs_hci_cmd_build_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
627*042d53a7SEvalZero BLETEST_CFG_SCAN_ITVL,
628*042d53a7SEvalZero BLETEST_CFG_SCAN_WINDOW,
629*042d53a7SEvalZero own_addr_type,
630*042d53a7SEvalZero BLETEST_CFG_SCAN_FILT_POLICY,
631*042d53a7SEvalZero buf, sizeof buf);
632*042d53a7SEvalZero assert(rc == 0);
633*042d53a7SEvalZero rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
634*042d53a7SEvalZero BLE_HCI_OCF_LE_SET_SCAN_PARAMS),
635*042d53a7SEvalZero buf, sizeof(buf));
636*042d53a7SEvalZero assert(rc == 0);
637*042d53a7SEvalZero if (rc == 0) {
638*042d53a7SEvalZero add_whitelist = BLETEST_CFG_SCAN_FILT_POLICY;
639*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
640*042d53a7SEvalZero if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
641*042d53a7SEvalZero rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk,
642*042d53a7SEvalZero g_bletest_adv_irk,
643*042d53a7SEvalZero g_bletest_cur_peer_addr,
644*042d53a7SEvalZero BLETEST_CFG_ADV_PEER_ADDR_TYPE);
645*042d53a7SEvalZero assert(rc == 0);
646*042d53a7SEvalZero
647*042d53a7SEvalZero rc = bletest_hci_le_enable_resolv_list(1);
648*042d53a7SEvalZero assert(rc == 0);
649*042d53a7SEvalZero }
650*042d53a7SEvalZero #endif
651*042d53a7SEvalZero if (add_whitelist & 1) {
652*042d53a7SEvalZero rc = bletest_hci_le_add_to_whitelist(g_bletest_cur_peer_addr,
653*042d53a7SEvalZero BLE_ADDR_RANDOM);
654*042d53a7SEvalZero assert(rc == 0);
655*042d53a7SEvalZero }
656*042d53a7SEvalZero }
657*042d53a7SEvalZero }
658*042d53a7SEvalZero
659*042d53a7SEvalZero void
bletest_execute_scanner(void)660*042d53a7SEvalZero bletest_execute_scanner(void)
661*042d53a7SEvalZero {
662*042d53a7SEvalZero int rc;
663*042d53a7SEvalZero
664*042d53a7SEvalZero /* Enable scanning */
665*042d53a7SEvalZero if ((int32_t)(ble_npl_time_get() - g_next_os_time) >= 0) {
666*042d53a7SEvalZero if (g_bletest_state) {
667*042d53a7SEvalZero rc = bletest_hci_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
668*042d53a7SEvalZero assert(rc == 0);
669*042d53a7SEvalZero g_bletest_state = 0;
670*042d53a7SEvalZero } else {
671*042d53a7SEvalZero rc = bletest_hci_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
672*042d53a7SEvalZero assert(rc == 0);
673*042d53a7SEvalZero g_bletest_state = 1;
674*042d53a7SEvalZero }
675*042d53a7SEvalZero g_next_os_time += (OS_TICKS_PER_SEC * 60);
676*042d53a7SEvalZero }
677*042d53a7SEvalZero }
678*042d53a7SEvalZero #endif
679*042d53a7SEvalZero
680*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
681*042d53a7SEvalZero void
bletest_init_initiator(void)682*042d53a7SEvalZero bletest_init_initiator(void)
683*042d53a7SEvalZero {
684*042d53a7SEvalZero int rc;
685*042d53a7SEvalZero uint8_t rand_addr[BLE_DEV_ADDR_LEN];
686*042d53a7SEvalZero struct hci_create_conn *hcc;
687*042d53a7SEvalZero
688*042d53a7SEvalZero /* Enable initiating */
689*042d53a7SEvalZero hcc = &g_cc;
690*042d53a7SEvalZero hcc->conn_itvl_max = BLETEST_CFG_CONN_ITVL;
691*042d53a7SEvalZero hcc->conn_itvl_min = BLETEST_CFG_CONN_ITVL;
692*042d53a7SEvalZero hcc->conn_latency = BLETEST_CFG_SLAVE_LATENCY;
693*042d53a7SEvalZero hcc->filter_policy = BLETEST_CFG_INIT_FILTER_POLICY;
694*042d53a7SEvalZero hcc->supervision_timeout = BLETEST_CFG_CONN_SPVN_TMO;
695*042d53a7SEvalZero hcc->scan_itvl = BLETEST_CFG_SCAN_ITVL;
696*042d53a7SEvalZero hcc->scan_window = BLETEST_CFG_SCAN_WINDOW;
697*042d53a7SEvalZero hcc->peer_addr_type = BLETEST_CFG_CONN_PEER_ADDR_TYPE;
698*042d53a7SEvalZero memcpy(hcc->peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
699*042d53a7SEvalZero if (hcc->peer_addr_type == BLE_HCI_CONN_PEER_ADDR_RANDOM) {
700*042d53a7SEvalZero hcc->peer_addr[5] |= 0xc0;
701*042d53a7SEvalZero }
702*042d53a7SEvalZero hcc->own_addr_type = BLETEST_CFG_CONN_OWN_ADDR_TYPE;
703*042d53a7SEvalZero hcc->min_ce_len = BLETEST_CFG_MIN_CE_LEN;
704*042d53a7SEvalZero hcc->max_ce_len = BLETEST_CFG_MAX_CE_LEN;
705*042d53a7SEvalZero
706*042d53a7SEvalZero console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
707*042d53a7SEvalZero hcc->peer_addr[0], hcc->peer_addr[1], hcc->peer_addr[2],
708*042d53a7SEvalZero hcc->peer_addr[3], hcc->peer_addr[4], hcc->peer_addr[5]);
709*042d53a7SEvalZero
710*042d53a7SEvalZero /* If we are using a random address, we need to set it */
711*042d53a7SEvalZero if (hcc->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
712*042d53a7SEvalZero memcpy(rand_addr, _g_dev_addr, BLE_DEV_ADDR_LEN);
713*042d53a7SEvalZero rand_addr[5] |= 0xc0;
714*042d53a7SEvalZero rc = bletest_hci_le_set_rand_addr(rand_addr);
715*042d53a7SEvalZero assert(rc == 0);
716*042d53a7SEvalZero }
717*042d53a7SEvalZero
718*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
719*042d53a7SEvalZero if ((hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) ||
720*042d53a7SEvalZero (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM)) {
721*042d53a7SEvalZero rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk,
722*042d53a7SEvalZero g_bletest_adv_irk,
723*042d53a7SEvalZero g_bletest_cur_peer_addr,
724*042d53a7SEvalZero BLETEST_CFG_ADV_PEER_ADDR_TYPE);
725*042d53a7SEvalZero assert(rc == 0);
726*042d53a7SEvalZero
727*042d53a7SEvalZero rc = bletest_hci_le_enable_resolv_list(1);
728*042d53a7SEvalZero assert(rc == 0);
729*042d53a7SEvalZero }
730*042d53a7SEvalZero #endif
731*042d53a7SEvalZero
732*042d53a7SEvalZero bletest_hci_le_create_connection(hcc);
733*042d53a7SEvalZero }
734*042d53a7SEvalZero
735*042d53a7SEvalZero void
bletest_execute_initiator(void)736*042d53a7SEvalZero bletest_execute_initiator(void)
737*042d53a7SEvalZero {
738*042d53a7SEvalZero int i;
739*042d53a7SEvalZero int rc;
740*042d53a7SEvalZero int8_t rssi;
741*042d53a7SEvalZero uint16_t handle;
742*042d53a7SEvalZero uint8_t new_chan_map[5];
743*042d53a7SEvalZero
744*042d53a7SEvalZero /*
745*042d53a7SEvalZero * Determine if there is an active connection for the current handle
746*042d53a7SEvalZero * we are trying to create. If so, start looking for the next one
747*042d53a7SEvalZero */
748*042d53a7SEvalZero if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
749*042d53a7SEvalZero handle = g_bletest_current_conns + 1;
750*042d53a7SEvalZero if (ble_hs_conn_find(handle)) {
751*042d53a7SEvalZero /* Set LED to slower blink rate */
752*042d53a7SEvalZero g_bletest_led_rate = OS_TICKS_PER_SEC;
753*042d53a7SEvalZero
754*042d53a7SEvalZero /* Ask for version information */
755*042d53a7SEvalZero rc = bletest_hci_rd_rem_version(handle);
756*042d53a7SEvalZero
757*042d53a7SEvalZero /* Ask for remote used features */
758*042d53a7SEvalZero rc = bletest_hci_le_read_rem_used_feat(handle);
759*042d53a7SEvalZero
760*042d53a7SEvalZero /* Add to current connections */
761*042d53a7SEvalZero if (!rc) {
762*042d53a7SEvalZero ++g_bletest_current_conns;
763*042d53a7SEvalZero
764*042d53a7SEvalZero /* Move to next connection */
765*042d53a7SEvalZero if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
766*042d53a7SEvalZero /* restart initiating */
767*042d53a7SEvalZero g_bletest_cur_peer_addr[5] += 1;
768*042d53a7SEvalZero _g_dev_addr[5] += 1;
769*042d53a7SEvalZero bletest_init_initiator();
770*042d53a7SEvalZero }
771*042d53a7SEvalZero }
772*042d53a7SEvalZero } else {
773*042d53a7SEvalZero bletest_hci_le_create_connection(&g_cc);
774*042d53a7SEvalZero }
775*042d53a7SEvalZero } else {
776*042d53a7SEvalZero if ((int32_t)(ble_npl_time_get() - g_next_os_time) >= 0) {
777*042d53a7SEvalZero if ((g_bletest_state == 1) || (g_bletest_state == 3)) {
778*042d53a7SEvalZero for (i = 0; i < g_bletest_current_conns; ++i) {
779*042d53a7SEvalZero if (ble_hs_conn_find(i + 1)) {
780*042d53a7SEvalZero bletest_hci_le_rd_chanmap(i+1);
781*042d53a7SEvalZero }
782*042d53a7SEvalZero }
783*042d53a7SEvalZero } else if (g_bletest_state == 2) {
784*042d53a7SEvalZero new_chan_map[0] = 0;
785*042d53a7SEvalZero new_chan_map[1] = 0x3;
786*042d53a7SEvalZero new_chan_map[2] = 0;
787*042d53a7SEvalZero new_chan_map[3] = 0x1F;
788*042d53a7SEvalZero new_chan_map[4] = 0;
789*042d53a7SEvalZero bletest_hci_le_set_host_chan_class(new_chan_map);
790*042d53a7SEvalZero } else if (g_bletest_state == 4) {
791*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
792*042d53a7SEvalZero struct hci_start_encrypt hsle;
793*042d53a7SEvalZero for (i = 0; i < g_bletest_current_conns; ++i) {
794*042d53a7SEvalZero if (ble_hs_conn_find(i + 1)) {
795*042d53a7SEvalZero hsle.connection_handle = i + 1;
796*042d53a7SEvalZero hsle.encrypted_diversifier = g_bletest_EDIV;
797*042d53a7SEvalZero hsle.random_number = g_bletest_RAND;
798*042d53a7SEvalZero swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
799*042d53a7SEvalZero 16);
800*042d53a7SEvalZero bletest_hci_le_start_encrypt(&hsle);
801*042d53a7SEvalZero }
802*042d53a7SEvalZero }
803*042d53a7SEvalZero #endif
804*042d53a7SEvalZero } else if (g_bletest_state == 8) {
805*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
806*042d53a7SEvalZero struct hci_start_encrypt hsle;
807*042d53a7SEvalZero for (i = 0; i < g_bletest_current_conns; ++i) {
808*042d53a7SEvalZero if (ble_hs_conn_find(i + 1)) {
809*042d53a7SEvalZero hsle.connection_handle = i + 1;
810*042d53a7SEvalZero hsle.encrypted_diversifier = g_bletest_EDIV;
811*042d53a7SEvalZero hsle.random_number = ~g_bletest_RAND;
812*042d53a7SEvalZero swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
813*042d53a7SEvalZero 16);
814*042d53a7SEvalZero bletest_hci_le_start_encrypt(&hsle);
815*042d53a7SEvalZero }
816*042d53a7SEvalZero }
817*042d53a7SEvalZero #endif
818*042d53a7SEvalZero } else {
819*042d53a7SEvalZero for (i = 0; i < g_bletest_current_conns; ++i) {
820*042d53a7SEvalZero if (ble_hs_conn_find(i + 1)) {
821*042d53a7SEvalZero ble_hs_hci_util_read_rssi(i+1, &rssi);
822*042d53a7SEvalZero }
823*042d53a7SEvalZero }
824*042d53a7SEvalZero }
825*042d53a7SEvalZero
826*042d53a7SEvalZero ++g_bletest_state;
827*042d53a7SEvalZero if (g_bletest_state > 9) {
828*042d53a7SEvalZero g_bletest_state = 9;
829*042d53a7SEvalZero }
830*042d53a7SEvalZero g_next_os_time = ble_npl_time_get() + OS_TICKS_PER_SEC * 3;
831*042d53a7SEvalZero }
832*042d53a7SEvalZero }
833*042d53a7SEvalZero }
834*042d53a7SEvalZero #endif
835*042d53a7SEvalZero
836*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
837*042d53a7SEvalZero /*
838*042d53a7SEvalZero * Test wrapper to get packets. Only get a packet if we have more than half
839*042d53a7SEvalZero * left
840*042d53a7SEvalZero */
841*042d53a7SEvalZero static struct os_mbuf *
bletest_get_packet(void)842*042d53a7SEvalZero bletest_get_packet(void)
843*042d53a7SEvalZero {
844*042d53a7SEvalZero struct os_mbuf *om;
845*042d53a7SEvalZero
846*042d53a7SEvalZero om = NULL;
847*042d53a7SEvalZero if (os_msys_num_free() >= 5) {
848*042d53a7SEvalZero om = os_msys_get_pkthdr(0, sizeof(struct ble_mbuf_hdr));
849*042d53a7SEvalZero }
850*042d53a7SEvalZero return om;
851*042d53a7SEvalZero }
852*042d53a7SEvalZero
853*042d53a7SEvalZero static struct os_mbuf *
bletest_send_packet(uint16_t handle)854*042d53a7SEvalZero bletest_send_packet(uint16_t handle)
855*042d53a7SEvalZero {
856*042d53a7SEvalZero int j;
857*042d53a7SEvalZero uint8_t val;
858*042d53a7SEvalZero struct os_mbuf *om;
859*042d53a7SEvalZero uint16_t pktlen;
860*042d53a7SEvalZero
861*042d53a7SEvalZero om = bletest_get_packet();
862*042d53a7SEvalZero if (om) {
863*042d53a7SEvalZero /* set payload length */
864*042d53a7SEvalZero #if BLETEST_THROUGHPUT_TEST
865*042d53a7SEvalZero pktlen = BLETEST_PKT_SIZE;
866*042d53a7SEvalZero #else
867*042d53a7SEvalZero #if (BLETEST_CFG_RAND_PKT_SIZE == 1)
868*042d53a7SEvalZero pktlen = rand() % (BLETEST_MAX_PKT_SIZE + 1);
869*042d53a7SEvalZero #else
870*042d53a7SEvalZero pktlen = BLETEST_PKT_SIZE;
871*042d53a7SEvalZero #endif
872*042d53a7SEvalZero #endif
873*042d53a7SEvalZero
874*042d53a7SEvalZero /* Put the HCI header in the mbuf */
875*042d53a7SEvalZero put_le16(om->om_data, handle);
876*042d53a7SEvalZero put_le16(om->om_data + 2, pktlen + 4);
877*042d53a7SEvalZero
878*042d53a7SEvalZero /* Place L2CAP header in packet */
879*042d53a7SEvalZero put_le16(om->om_data + 4, pktlen);
880*042d53a7SEvalZero om->om_data[6] = 0;
881*042d53a7SEvalZero om->om_data[7] = 0;
882*042d53a7SEvalZero om->om_len = 8;
883*042d53a7SEvalZero OS_MBUF_PKTHDR(om)->omp_len = 8;
884*042d53a7SEvalZero
885*042d53a7SEvalZero /* Fill with incrementing pattern (starting from 1) */
886*042d53a7SEvalZero for (j = 0; j < pktlen; ++j) {
887*042d53a7SEvalZero val = j + 1;
888*042d53a7SEvalZero os_mbuf_append(om, &val, 1);
889*042d53a7SEvalZero }
890*042d53a7SEvalZero
891*042d53a7SEvalZero /* Transmit it */
892*042d53a7SEvalZero ble_hci_trans_hs_acl_tx(om);
893*042d53a7SEvalZero }
894*042d53a7SEvalZero
895*042d53a7SEvalZero return om;
896*042d53a7SEvalZero }
897*042d53a7SEvalZero
898*042d53a7SEvalZero static void
bletest_execute_advertiser(void)899*042d53a7SEvalZero bletest_execute_advertiser(void)
900*042d53a7SEvalZero {
901*042d53a7SEvalZero int i;
902*042d53a7SEvalZero #if (BLETEST_CONCURRENT_CONN_TEST == 1)
903*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
904*042d53a7SEvalZero uint16_t mask;
905*042d53a7SEvalZero uint16_t reply_handle;
906*042d53a7SEvalZero #endif
907*042d53a7SEvalZero #endif
908*042d53a7SEvalZero int rc;
909*042d53a7SEvalZero uint16_t handle;
910*042d53a7SEvalZero struct os_mbuf *om;
911*042d53a7SEvalZero #if (BLETEST_THROUGHPUT_TEST == 1)
912*042d53a7SEvalZero os_sr_t sr;
913*042d53a7SEvalZero uint16_t completed_pkts;
914*042d53a7SEvalZero #endif
915*042d53a7SEvalZero
916*042d53a7SEvalZero /* See if we should start advertising again */
917*042d53a7SEvalZero if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
918*042d53a7SEvalZero handle = g_bletest_current_conns + 1;
919*042d53a7SEvalZero if (ble_hs_conn_find(handle)) {
920*042d53a7SEvalZero /* Set LED to slower blink rate */
921*042d53a7SEvalZero g_bletest_led_rate = OS_TICKS_PER_SEC;
922*042d53a7SEvalZero
923*042d53a7SEvalZero #if (BLETEST_THROUGHPUT_TEST == 1)
924*042d53a7SEvalZero /* Set next os time to 10 seconds after 1st connection */
925*042d53a7SEvalZero if (g_next_os_time == 0) {
926*042d53a7SEvalZero g_next_os_time = os_time_get() + (10 * OS_TICKS_PER_SEC);
927*042d53a7SEvalZero g_bletest_handle = handle;
928*042d53a7SEvalZero }
929*042d53a7SEvalZero #endif
930*042d53a7SEvalZero /* Send the remote used features command */
931*042d53a7SEvalZero rc = bletest_hci_le_read_rem_used_feat(handle);
932*042d53a7SEvalZero if (rc) {
933*042d53a7SEvalZero return;
934*042d53a7SEvalZero }
935*042d53a7SEvalZero
936*042d53a7SEvalZero /* Send the remote read version command */
937*042d53a7SEvalZero rc = bletest_hci_rd_rem_version(handle);
938*042d53a7SEvalZero if (rc) {
939*042d53a7SEvalZero return;
940*042d53a7SEvalZero }
941*042d53a7SEvalZero
942*042d53a7SEvalZero /* set conn update time */
943*042d53a7SEvalZero g_bletest_conn_upd_time = ble_npl_time_get() + (OS_TICKS_PER_SEC * 5);
944*042d53a7SEvalZero g_bletest_start_update = 1;
945*042d53a7SEvalZero
946*042d53a7SEvalZero /* Add to current connections */
947*042d53a7SEvalZero ++g_bletest_current_conns;
948*042d53a7SEvalZero
949*042d53a7SEvalZero /* Move to next connection */
950*042d53a7SEvalZero if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
951*042d53a7SEvalZero /* restart initiating */
952*042d53a7SEvalZero g_bletest_cur_peer_addr[5] += 1;
953*042d53a7SEvalZero _g_dev_addr[5] += 1;
954*042d53a7SEvalZero #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
955*042d53a7SEvalZero bletest_init_advertising(0,0);
956*042d53a7SEvalZero bletest_hci_le_set_multi_adv_enable(1, 0);
957*042d53a7SEvalZero #else
958*042d53a7SEvalZero bletest_init_advertising();
959*042d53a7SEvalZero bletest_hci_le_set_adv_enable(1);
960*042d53a7SEvalZero #endif
961*042d53a7SEvalZero }
962*042d53a7SEvalZero } else {
963*042d53a7SEvalZero /* If we failed to start advertising we should keep trying */
964*042d53a7SEvalZero #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
965*042d53a7SEvalZero bletest_hci_le_set_multi_adv_enable(1, 0);
966*042d53a7SEvalZero #else
967*042d53a7SEvalZero bletest_hci_le_set_adv_enable(1);
968*042d53a7SEvalZero #endif
969*042d53a7SEvalZero }
970*042d53a7SEvalZero }
971*042d53a7SEvalZero #if 0
972*042d53a7SEvalZero if (g_bletest_start_update) {
973*042d53a7SEvalZero if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) {
974*042d53a7SEvalZero bletest_send_conn_update(1);
975*042d53a7SEvalZero g_bletest_start_update = 0;
976*042d53a7SEvalZero }
977*042d53a7SEvalZero }
978*042d53a7SEvalZero #endif
979*042d53a7SEvalZero
980*042d53a7SEvalZero #if (BLETEST_CONCURRENT_CONN_TEST == 1)
981*042d53a7SEvalZero /* See if it is time to hand a data packet to the connection */
982*042d53a7SEvalZero if ((int32_t)(ble_npl_time_get() - g_next_os_time) >= 0) {
983*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
984*042d53a7SEvalZero /* Do we need to send a LTK reply? */
985*042d53a7SEvalZero mask = 1;
986*042d53a7SEvalZero reply_handle = 1;
987*042d53a7SEvalZero while (g_bletest_ltk_reply_handle && mask) {
988*042d53a7SEvalZero if (g_bletest_ltk_reply_handle & mask) {
989*042d53a7SEvalZero bletest_send_ltk_req_reply(reply_handle);
990*042d53a7SEvalZero //bletest_send_ltk_req_neg_reply(reply_handle);
991*042d53a7SEvalZero g_bletest_ltk_reply_handle &= ~mask;
992*042d53a7SEvalZero }
993*042d53a7SEvalZero ++reply_handle;
994*042d53a7SEvalZero mask <<= 1;
995*042d53a7SEvalZero }
996*042d53a7SEvalZero #endif
997*042d53a7SEvalZero if (g_bletest_current_conns) {
998*042d53a7SEvalZero for (i = 0; i < g_bletest_current_conns; ++i) {
999*042d53a7SEvalZero if ((g_last_handle_used == 0) ||
1000*042d53a7SEvalZero (g_last_handle_used > g_bletest_current_conns)) {
1001*042d53a7SEvalZero g_last_handle_used = 1;
1002*042d53a7SEvalZero }
1003*042d53a7SEvalZero handle = g_last_handle_used;
1004*042d53a7SEvalZero if (ble_hs_conn_find(handle)) {
1005*042d53a7SEvalZero om = bletest_send_packet(handle);
1006*042d53a7SEvalZero if (om) {
1007*042d53a7SEvalZero /* Increment last handle used */
1008*042d53a7SEvalZero ++g_last_handle_used;
1009*042d53a7SEvalZero }
1010*042d53a7SEvalZero } else {
1011*042d53a7SEvalZero ++g_last_handle_used;
1012*042d53a7SEvalZero }
1013*042d53a7SEvalZero }
1014*042d53a7SEvalZero }
1015*042d53a7SEvalZero g_next_os_time = ble_npl_time_get() + OS_TICKS_PER_SEC;
1016*042d53a7SEvalZero }
1017*042d53a7SEvalZero #endif
1018*042d53a7SEvalZero
1019*042d53a7SEvalZero #if (BLETEST_THROUGHPUT_TEST == 1)
1020*042d53a7SEvalZero /* Nothing to do if no connections */
1021*042d53a7SEvalZero if (!g_bletest_current_conns) {
1022*042d53a7SEvalZero return;
1023*042d53a7SEvalZero }
1024*042d53a7SEvalZero
1025*042d53a7SEvalZero /* See if it is time to start throughput testing */
1026*042d53a7SEvalZero if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
1027*042d53a7SEvalZero /* Keep window full */
1028*042d53a7SEvalZero OS_ENTER_CRITICAL(sr);
1029*042d53a7SEvalZero completed_pkts = g_bletest_completed_pkts;
1030*042d53a7SEvalZero g_bletest_completed_pkts = 0;
1031*042d53a7SEvalZero OS_EXIT_CRITICAL(sr);
1032*042d53a7SEvalZero
1033*042d53a7SEvalZero assert(g_bletest_outstanding_pkts >= completed_pkts);
1034*042d53a7SEvalZero g_bletest_outstanding_pkts -= completed_pkts;
1035*042d53a7SEvalZero
1036*042d53a7SEvalZero while (g_bletest_outstanding_pkts < 20) {
1037*042d53a7SEvalZero om = bletest_send_packet(g_bletest_handle);
1038*042d53a7SEvalZero if (om) {
1039*042d53a7SEvalZero ++g_bletest_outstanding_pkts;
1040*042d53a7SEvalZero }
1041*042d53a7SEvalZero }
1042*042d53a7SEvalZero }
1043*042d53a7SEvalZero #endif /* XXX: throughput test */
1044*042d53a7SEvalZero }
1045*042d53a7SEvalZero #endif /* XXX: BLETEST_ROLE_ADVERTISER */
1046*042d53a7SEvalZero
1047*042d53a7SEvalZero /**
1048*042d53a7SEvalZero * Main bletest function. Called by the task timer every 50 msecs.
1049*042d53a7SEvalZero *
1050*042d53a7SEvalZero */
1051*042d53a7SEvalZero void
bletest_execute(void)1052*042d53a7SEvalZero bletest_execute(void)
1053*042d53a7SEvalZero {
1054*042d53a7SEvalZero /* Toggle LED at set rate */
1055*042d53a7SEvalZero if ((int32_t)(ble_npl_time_get() - g_bletest_next_led_time) >= 0) {
1056*042d53a7SEvalZero // hal_gpio_toggle(LED_BLINK_PIN);
1057*042d53a7SEvalZero g_bletest_next_led_time = ble_npl_time_get() + g_bletest_led_rate;
1058*042d53a7SEvalZero }
1059*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
1060*042d53a7SEvalZero bletest_execute_advertiser();
1061*042d53a7SEvalZero #endif
1062*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
1063*042d53a7SEvalZero bletest_execute_scanner();
1064*042d53a7SEvalZero #endif
1065*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
1066*042d53a7SEvalZero bletest_execute_initiator();
1067*042d53a7SEvalZero #endif
1068*042d53a7SEvalZero }
1069*042d53a7SEvalZero
1070*042d53a7SEvalZero /**
1071*042d53a7SEvalZero * Callback when BLE test timer expires.
1072*042d53a7SEvalZero *
1073*042d53a7SEvalZero * @param arg
1074*042d53a7SEvalZero */
1075*042d53a7SEvalZero void
bletest_timer_cb(struct ble_npl_event * ev)1076*042d53a7SEvalZero bletest_timer_cb(struct ble_npl_event *ev)
1077*042d53a7SEvalZero {
1078*042d53a7SEvalZero /* Call the bletest code */
1079*042d53a7SEvalZero bletest_execute();
1080*042d53a7SEvalZero
1081*042d53a7SEvalZero /* Re-start the timer (run every 10 msecs) */
1082*042d53a7SEvalZero ble_npl_callout_reset(&g_bletest_timer, OS_TICKS_PER_SEC / 100);
1083*042d53a7SEvalZero }
1084*042d53a7SEvalZero
1085*042d53a7SEvalZero /**
1086*042d53a7SEvalZero * BLE test task
1087*042d53a7SEvalZero *
1088*042d53a7SEvalZero * @param arg
1089*042d53a7SEvalZero */
1090*042d53a7SEvalZero void
bletest_task_handler(void * arg)1091*042d53a7SEvalZero bletest_task_handler(void *arg)
1092*042d53a7SEvalZero {
1093*042d53a7SEvalZero int rc;
1094*042d53a7SEvalZero uint64_t rand64;
1095*042d53a7SEvalZero uint64_t event_mask;
1096*042d53a7SEvalZero
1097*042d53a7SEvalZero /* Set LED blink rate */
1098*042d53a7SEvalZero g_bletest_led_rate = OS_TICKS_PER_SEC / 20;
1099*042d53a7SEvalZero
1100*042d53a7SEvalZero /* Wait one second before starting test task */
1101*042d53a7SEvalZero ble_npl_time_delay(OS_TICKS_PER_SEC);
1102*042d53a7SEvalZero
1103*042d53a7SEvalZero /* Initialize the host timer */
1104*042d53a7SEvalZero ble_npl_callout_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb,
1105*042d53a7SEvalZero NULL);
1106*042d53a7SEvalZero
1107*042d53a7SEvalZero ble_hs_dbg_set_sync_state(BLE_HS_SYNC_STATE_GOOD);
1108*042d53a7SEvalZero
1109*042d53a7SEvalZero /* Send the reset command first */
1110*042d53a7SEvalZero rc = bletest_hci_reset_ctlr();
1111*042d53a7SEvalZero assert(rc == 0);
1112*042d53a7SEvalZero
1113*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
1114*042d53a7SEvalZero /* Initialize the advertiser */
1115*042d53a7SEvalZero console_printf("Starting BLE test task as advertiser\n");
1116*042d53a7SEvalZero #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
1117*042d53a7SEvalZero /* Start up all advertising instances except default one */
1118*042d53a7SEvalZero bletest_init_adv_instances();
1119*042d53a7SEvalZero
1120*042d53a7SEvalZero /* Start advertising on instance 0 at 0 dbm */
1121*042d53a7SEvalZero bletest_init_advertising(0, 0);
1122*042d53a7SEvalZero #else
1123*042d53a7SEvalZero bletest_init_advertising();
1124*042d53a7SEvalZero #endif
1125*042d53a7SEvalZero #endif
1126*042d53a7SEvalZero
1127*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
1128*042d53a7SEvalZero /* Initialize the scanner */
1129*042d53a7SEvalZero console_printf("Starting BLE test task as scanner\n");
1130*042d53a7SEvalZero bletest_init_scanner();
1131*042d53a7SEvalZero #endif
1132*042d53a7SEvalZero
1133*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
1134*042d53a7SEvalZero /* Initialize the scanner */
1135*042d53a7SEvalZero console_printf("Starting BLE test task as initiator\n");
1136*042d53a7SEvalZero bletest_init_initiator();
1137*042d53a7SEvalZero #endif
1138*042d53a7SEvalZero
1139*042d53a7SEvalZero /* Read unique HW id */
1140*042d53a7SEvalZero // rc = hal_bsp_hw_id((void *)&g_bletest_hw_id[0], sizeof(g_bletest_hw_id));
1141*042d53a7SEvalZero // assert(rc == 16);
1142*042d53a7SEvalZero console_printf("HW id=%04x%04x%04x%04x\n",
1143*042d53a7SEvalZero (unsigned int)g_bletest_hw_id[0],
1144*042d53a7SEvalZero (unsigned int)g_bletest_hw_id[1],
1145*042d53a7SEvalZero (unsigned int)g_bletest_hw_id[2],
1146*042d53a7SEvalZero (unsigned int)g_bletest_hw_id[3]);
1147*042d53a7SEvalZero
1148*042d53a7SEvalZero /* Set the event mask we want to display */
1149*042d53a7SEvalZero event_mask = 0x7FF;
1150*042d53a7SEvalZero rc = bletest_hci_le_set_event_mask(event_mask);
1151*042d53a7SEvalZero assert(rc == 0);
1152*042d53a7SEvalZero
1153*042d53a7SEvalZero /* Turn on all events */
1154*042d53a7SEvalZero event_mask = 0xffffffffffffffff;
1155*042d53a7SEvalZero rc = bletest_hci_set_event_mask(event_mask);
1156*042d53a7SEvalZero assert(rc == 0);
1157*042d53a7SEvalZero
1158*042d53a7SEvalZero /* Read device address */
1159*042d53a7SEvalZero rc = bletest_hci_rd_bd_addr();
1160*042d53a7SEvalZero assert(rc == 0);
1161*042d53a7SEvalZero
1162*042d53a7SEvalZero /* Read local features */
1163*042d53a7SEvalZero rc = bletest_hci_rd_local_feat();
1164*042d53a7SEvalZero assert(rc == 0);
1165*042d53a7SEvalZero
1166*042d53a7SEvalZero /* Read local commands */
1167*042d53a7SEvalZero rc = bletest_hci_rd_local_supp_cmd();
1168*042d53a7SEvalZero assert(rc == 0);
1169*042d53a7SEvalZero
1170*042d53a7SEvalZero /* Read version */
1171*042d53a7SEvalZero rc = bletest_hci_rd_local_version();
1172*042d53a7SEvalZero assert(rc == 0);
1173*042d53a7SEvalZero
1174*042d53a7SEvalZero /* Read supported states */
1175*042d53a7SEvalZero rc = bletest_hci_le_read_supp_states();
1176*042d53a7SEvalZero assert(rc == 0);
1177*042d53a7SEvalZero
1178*042d53a7SEvalZero /* Read maximum data length */
1179*042d53a7SEvalZero rc = bletest_hci_le_rd_max_datalen();
1180*042d53a7SEvalZero assert(rc == 0);
1181*042d53a7SEvalZero
1182*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
1183*042d53a7SEvalZero /* Read suggested data length */
1184*042d53a7SEvalZero rc = bletest_hci_le_rd_sugg_datalen();
1185*042d53a7SEvalZero assert(rc == 0);
1186*042d53a7SEvalZero
1187*042d53a7SEvalZero /* write suggested default data length */
1188*042d53a7SEvalZero rc = bletest_hci_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS,
1189*042d53a7SEvalZero BLETEST_CFG_SUGG_DEF_TXTIME);
1190*042d53a7SEvalZero assert(rc == 0);
1191*042d53a7SEvalZero
1192*042d53a7SEvalZero /* Read suggested data length */
1193*042d53a7SEvalZero rc = bletest_hci_le_rd_sugg_datalen();
1194*042d53a7SEvalZero assert(rc == 0);
1195*042d53a7SEvalZero
1196*042d53a7SEvalZero /* Set data length (note: we know there is no connection; just a test) */
1197*042d53a7SEvalZero rc = bletest_hci_le_set_datalen(0x1234, BLETEST_CFG_SUGG_DEF_TXOCTETS,
1198*042d53a7SEvalZero BLETEST_CFG_SUGG_DEF_TXTIME);
1199*042d53a7SEvalZero assert(rc != 0);
1200*042d53a7SEvalZero #endif
1201*042d53a7SEvalZero
1202*042d53a7SEvalZero /* Encrypt a block */
1203*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1204*042d53a7SEvalZero rc = bletest_hci_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key,
1205*042d53a7SEvalZero (uint8_t *)g_ble_ll_encrypt_test_plain_text);
1206*042d53a7SEvalZero assert(rc == 0);
1207*042d53a7SEvalZero #endif
1208*042d53a7SEvalZero
1209*042d53a7SEvalZero /* Get a random number */
1210*042d53a7SEvalZero rc = ble_hs_hci_util_rand(&rand64, 8);
1211*042d53a7SEvalZero assert(rc == 0);
1212*042d53a7SEvalZero
1213*042d53a7SEvalZero /* Wait some time before starting */
1214*042d53a7SEvalZero ble_npl_time_delay(OS_TICKS_PER_SEC);
1215*042d53a7SEvalZero
1216*042d53a7SEvalZero /* Init state */
1217*042d53a7SEvalZero g_bletest_state = 0;
1218*042d53a7SEvalZero
1219*042d53a7SEvalZero /* Begin advertising if we are an advertiser */
1220*042d53a7SEvalZero #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
1221*042d53a7SEvalZero #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
1222*042d53a7SEvalZero rc = bletest_hci_le_set_multi_adv_enable(1, 0);
1223*042d53a7SEvalZero assert(rc == 0);
1224*042d53a7SEvalZero #else
1225*042d53a7SEvalZero rc = bletest_hci_le_set_adv_enable(1);
1226*042d53a7SEvalZero assert(rc == 0);
1227*042d53a7SEvalZero #endif
1228*042d53a7SEvalZero #endif
1229*042d53a7SEvalZero
1230*042d53a7SEvalZero bletest_timer_cb(NULL);
1231*042d53a7SEvalZero }
1232*042d53a7SEvalZero
1233*042d53a7SEvalZero extern int nimble_ble_enable(void);
1234*042d53a7SEvalZero /**
1235*042d53a7SEvalZero * main
1236*042d53a7SEvalZero *
1237*042d53a7SEvalZero * The main task for the project. This function initializes the packages,
1238*042d53a7SEvalZero * then starts serving events from default event queue.
1239*042d53a7SEvalZero *
1240*042d53a7SEvalZero * @return int NOTE: this function should never return!
1241*042d53a7SEvalZero */
bletest(void)1242*042d53a7SEvalZero static int bletest(void)
1243*042d53a7SEvalZero {
1244*042d53a7SEvalZero rt_thread_t tid;
1245*042d53a7SEvalZero
1246*042d53a7SEvalZero /* startup bluetooth host stack*/
1247*042d53a7SEvalZero ble_hs_thread_startup();
1248*042d53a7SEvalZero
1249*042d53a7SEvalZero /* Dummy device address */
1250*042d53a7SEvalZero #if BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER
1251*042d53a7SEvalZero _g_dev_addr[0] = 0x00;
1252*042d53a7SEvalZero _g_dev_addr[1] = 0x00;
1253*042d53a7SEvalZero _g_dev_addr[2] = 0x00;
1254*042d53a7SEvalZero _g_dev_addr[3] = 0x88;
1255*042d53a7SEvalZero _g_dev_addr[4] = 0x88;
1256*042d53a7SEvalZero _g_dev_addr[5] = 0x08;
1257*042d53a7SEvalZero
1258*042d53a7SEvalZero g_bletest_cur_peer_addr[0] = 0x00;
1259*042d53a7SEvalZero g_bletest_cur_peer_addr[1] = 0x00;
1260*042d53a7SEvalZero g_bletest_cur_peer_addr[2] = 0x00;
1261*042d53a7SEvalZero g_bletest_cur_peer_addr[3] = 0x99;
1262*042d53a7SEvalZero g_bletest_cur_peer_addr[4] = 0x99;
1263*042d53a7SEvalZero g_bletest_cur_peer_addr[5] = 0x09;
1264*042d53a7SEvalZero #else
1265*042d53a7SEvalZero _g_dev_addr[0] = 0x00;
1266*042d53a7SEvalZero _g_dev_addr[1] = 0x00;
1267*042d53a7SEvalZero _g_dev_addr[2] = 0x00;
1268*042d53a7SEvalZero _g_dev_addr[3] = 0x99;
1269*042d53a7SEvalZero _g_dev_addr[4] = 0x99;
1270*042d53a7SEvalZero _g_dev_addr[5] = 0x09;
1271*042d53a7SEvalZero
1272*042d53a7SEvalZero g_bletest_cur_peer_addr[0] = 0x00;
1273*042d53a7SEvalZero g_bletest_cur_peer_addr[1] = 0x00;
1274*042d53a7SEvalZero g_bletest_cur_peer_addr[2] = 0x00;
1275*042d53a7SEvalZero g_bletest_cur_peer_addr[3] = 0x88;
1276*042d53a7SEvalZero g_bletest_cur_peer_addr[4] = 0x88;
1277*042d53a7SEvalZero g_bletest_cur_peer_addr[5] = 0x08;
1278*042d53a7SEvalZero #endif
1279*042d53a7SEvalZero
1280*042d53a7SEvalZero /* Set the led pin as an output */
1281*042d53a7SEvalZero // g_led_pin = LED_BLINK_PIN;
1282*042d53a7SEvalZero // hal_gpio_init_out(g_led_pin, 1);
1283*042d53a7SEvalZero
1284*042d53a7SEvalZero /* Initialize eventq for bletest task */
1285*042d53a7SEvalZero ble_npl_eventq_init(&g_bletest_evq);
1286*042d53a7SEvalZero
1287*042d53a7SEvalZero tid = rt_thread_create("ble_test", bletest_task_handler, RT_NULL, 1024, 10, 10);
1288*042d53a7SEvalZero if(tid != RT_NULL)
1289*042d53a7SEvalZero rt_thread_startup(tid);
1290*042d53a7SEvalZero
1291*042d53a7SEvalZero return 0;
1292*042d53a7SEvalZero }
1293*042d53a7SEvalZero MSH_CMD_EXPORT_ALIAS(bletest, bletest, "bluetooth test sample");
1294