xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/src/ble_hs_startup.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 <stddef.h>
21*042d53a7SEvalZero #include <string.h>
22*042d53a7SEvalZero #include "host/ble_hs.h"
23*042d53a7SEvalZero #include "host/ble_hs_hci.h"
24*042d53a7SEvalZero #include "ble_hs_priv.h"
25*042d53a7SEvalZero 
26*042d53a7SEvalZero #if !MYNEWT_VAL(BLE_DEVICE)
27*042d53a7SEvalZero static int
ble_hs_startup_read_sup_f_tx(void)28*042d53a7SEvalZero ble_hs_startup_read_sup_f_tx(void)
29*042d53a7SEvalZero {
30*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
31*042d53a7SEvalZero     uint8_t ack_params_len;
32*042d53a7SEvalZero     int rc;
33*042d53a7SEvalZero 
34*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
35*042d53a7SEvalZero                                       BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT),
36*042d53a7SEvalZero                            NULL,0, ack_params, sizeof ack_params,
37*042d53a7SEvalZero                            &ack_params_len);
38*042d53a7SEvalZero     if (rc != 0) {
39*042d53a7SEvalZero         return rc;
40*042d53a7SEvalZero     }
41*042d53a7SEvalZero 
42*042d53a7SEvalZero     if (ack_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
43*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
44*042d53a7SEvalZero     }
45*042d53a7SEvalZero 
46*042d53a7SEvalZero     /* for now we don't use it outside of init sequence so check this here
47*042d53a7SEvalZero      * LE Supported (Controller) byte 4, bit 6
48*042d53a7SEvalZero      */
49*042d53a7SEvalZero     if (!(ack_params[4] & 0x60)) {
50*042d53a7SEvalZero         BLE_HS_LOG(ERROR, "Controller doesn't support LE\n");
51*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
52*042d53a7SEvalZero     }
53*042d53a7SEvalZero 
54*042d53a7SEvalZero     return 0;
55*042d53a7SEvalZero }
56*042d53a7SEvalZero #endif
57*042d53a7SEvalZero 
58*042d53a7SEvalZero static int
ble_hs_startup_read_local_ver_tx(void)59*042d53a7SEvalZero ble_hs_startup_read_local_ver_tx(void)
60*042d53a7SEvalZero {
61*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_RD_LOC_VER_INFO_RSPLEN];
62*042d53a7SEvalZero     uint8_t ack_params_len;
63*042d53a7SEvalZero     uint8_t hci_version;
64*042d53a7SEvalZero     int rc;
65*042d53a7SEvalZero 
66*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
67*042d53a7SEvalZero                                       BLE_HCI_OCF_IP_RD_LOCAL_VER),
68*042d53a7SEvalZero                            NULL,0, ack_params, sizeof ack_params,
69*042d53a7SEvalZero                            &ack_params_len);
70*042d53a7SEvalZero     if (rc != 0) {
71*042d53a7SEvalZero         return rc;
72*042d53a7SEvalZero     }
73*042d53a7SEvalZero 
74*042d53a7SEvalZero     if (ack_params_len != BLE_HCI_RD_LOC_VER_INFO_RSPLEN) {
75*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
76*042d53a7SEvalZero     }
77*042d53a7SEvalZero 
78*042d53a7SEvalZero     /* For now we are interested only in HCI Version */
79*042d53a7SEvalZero     hci_version = ack_params[0];
80*042d53a7SEvalZero     ble_hs_hci_set_hci_version(hci_version);
81*042d53a7SEvalZero 
82*042d53a7SEvalZero     return 0;
83*042d53a7SEvalZero }
84*042d53a7SEvalZero 
85*042d53a7SEvalZero static int
ble_hs_startup_le_read_sup_f_tx(void)86*042d53a7SEvalZero ble_hs_startup_le_read_sup_f_tx(void)
87*042d53a7SEvalZero {
88*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN];
89*042d53a7SEvalZero     uint8_t ack_params_len;
90*042d53a7SEvalZero     uint32_t feat;
91*042d53a7SEvalZero     int rc;
92*042d53a7SEvalZero 
93*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
94*042d53a7SEvalZero                                       BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT),
95*042d53a7SEvalZero                            NULL,0, ack_params, sizeof ack_params,
96*042d53a7SEvalZero                            &ack_params_len);
97*042d53a7SEvalZero     if (rc != 0) {
98*042d53a7SEvalZero         return rc;
99*042d53a7SEvalZero     }
100*042d53a7SEvalZero 
101*042d53a7SEvalZero     if (ack_params_len != BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN) {
102*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
103*042d53a7SEvalZero     }
104*042d53a7SEvalZero 
105*042d53a7SEvalZero     /* For now 32-bits of features is enough */
106*042d53a7SEvalZero     feat = get_le32(ack_params);
107*042d53a7SEvalZero     ble_hs_hci_set_le_supported_feat(feat);
108*042d53a7SEvalZero 
109*042d53a7SEvalZero     return 0;
110*042d53a7SEvalZero }
111*042d53a7SEvalZero 
112*042d53a7SEvalZero static int
ble_hs_startup_le_read_buf_sz_tx(uint16_t * out_pktlen,uint8_t * out_max_pkts)113*042d53a7SEvalZero ble_hs_startup_le_read_buf_sz_tx(uint16_t *out_pktlen, uint8_t *out_max_pkts)
114*042d53a7SEvalZero {
115*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_RD_BUF_SIZE_RSPLEN];
116*042d53a7SEvalZero     uint8_t ack_params_len;
117*042d53a7SEvalZero     int rc;
118*042d53a7SEvalZero 
119*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
120*042d53a7SEvalZero                                       BLE_HCI_OCF_LE_RD_BUF_SIZE), NULL, 0,
121*042d53a7SEvalZero                            ack_params, sizeof ack_params, &ack_params_len);
122*042d53a7SEvalZero     if (rc != 0) {
123*042d53a7SEvalZero         return rc;
124*042d53a7SEvalZero     }
125*042d53a7SEvalZero 
126*042d53a7SEvalZero     if (ack_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN) {
127*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
128*042d53a7SEvalZero     }
129*042d53a7SEvalZero 
130*042d53a7SEvalZero     *out_pktlen = get_le16(ack_params + 0);
131*042d53a7SEvalZero     *out_max_pkts = ack_params[2];
132*042d53a7SEvalZero 
133*042d53a7SEvalZero     return 0;
134*042d53a7SEvalZero }
135*042d53a7SEvalZero 
136*042d53a7SEvalZero static int
ble_hs_startup_read_buf_sz_tx(uint16_t * out_pktlen,uint16_t * out_max_pkts)137*042d53a7SEvalZero ble_hs_startup_read_buf_sz_tx(uint16_t *out_pktlen, uint16_t *out_max_pkts)
138*042d53a7SEvalZero {
139*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_IP_RD_BUF_SIZE_RSPLEN];
140*042d53a7SEvalZero     uint8_t ack_params_len;
141*042d53a7SEvalZero     int rc;
142*042d53a7SEvalZero 
143*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
144*042d53a7SEvalZero                                       BLE_HCI_OCF_IP_RD_BUF_SIZE), NULL, 0,
145*042d53a7SEvalZero                            ack_params, sizeof ack_params, &ack_params_len);
146*042d53a7SEvalZero     if (rc != 0) {
147*042d53a7SEvalZero         return rc;
148*042d53a7SEvalZero     }
149*042d53a7SEvalZero 
150*042d53a7SEvalZero     if (ack_params_len != BLE_HCI_IP_RD_BUF_SIZE_RSPLEN) {
151*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
152*042d53a7SEvalZero     }
153*042d53a7SEvalZero 
154*042d53a7SEvalZero     *out_pktlen = get_le16(ack_params + 0);
155*042d53a7SEvalZero     *out_max_pkts = get_le16(ack_params + 3);
156*042d53a7SEvalZero 
157*042d53a7SEvalZero     return 0;
158*042d53a7SEvalZero }
159*042d53a7SEvalZero 
160*042d53a7SEvalZero static int
ble_hs_startup_read_buf_sz(void)161*042d53a7SEvalZero ble_hs_startup_read_buf_sz(void)
162*042d53a7SEvalZero {
163*042d53a7SEvalZero     uint16_t le_pktlen = 0;
164*042d53a7SEvalZero     uint16_t max_pkts = 0;
165*042d53a7SEvalZero     uint16_t pktlen = 0;
166*042d53a7SEvalZero     uint8_t le_max_pkts = 0;
167*042d53a7SEvalZero     int rc;
168*042d53a7SEvalZero 
169*042d53a7SEvalZero     rc = ble_hs_startup_le_read_buf_sz_tx(&le_pktlen, &le_max_pkts);
170*042d53a7SEvalZero     if (rc != 0) {
171*042d53a7SEvalZero         return rc;
172*042d53a7SEvalZero     }
173*042d53a7SEvalZero 
174*042d53a7SEvalZero     if (le_pktlen != 0) {
175*042d53a7SEvalZero         pktlen = le_pktlen;
176*042d53a7SEvalZero         max_pkts = le_max_pkts;
177*042d53a7SEvalZero     } else {
178*042d53a7SEvalZero         rc = ble_hs_startup_read_buf_sz_tx(&pktlen, &max_pkts);
179*042d53a7SEvalZero         if (rc != 0) {
180*042d53a7SEvalZero             return rc;
181*042d53a7SEvalZero         }
182*042d53a7SEvalZero     }
183*042d53a7SEvalZero 
184*042d53a7SEvalZero     rc = ble_hs_hci_set_buf_sz(pktlen, max_pkts);
185*042d53a7SEvalZero     if (rc != 0) {
186*042d53a7SEvalZero         return rc;
187*042d53a7SEvalZero     }
188*042d53a7SEvalZero 
189*042d53a7SEvalZero     return 0;
190*042d53a7SEvalZero }
191*042d53a7SEvalZero 
192*042d53a7SEvalZero static int
ble_hs_startup_read_bd_addr(void)193*042d53a7SEvalZero ble_hs_startup_read_bd_addr(void)
194*042d53a7SEvalZero {
195*042d53a7SEvalZero     uint8_t ack_params[BLE_HCI_IP_RD_BD_ADDR_ACK_PARAM_LEN];
196*042d53a7SEvalZero     uint8_t ack_params_len;
197*042d53a7SEvalZero     int rc;
198*042d53a7SEvalZero 
199*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
200*042d53a7SEvalZero                                       BLE_HCI_OCF_IP_RD_BD_ADDR),
201*042d53a7SEvalZero                            NULL, 0, ack_params, sizeof ack_params,
202*042d53a7SEvalZero                            &ack_params_len);
203*042d53a7SEvalZero     if (rc != 0) {
204*042d53a7SEvalZero         return rc;
205*042d53a7SEvalZero     }
206*042d53a7SEvalZero 
207*042d53a7SEvalZero     if (ack_params_len != sizeof ack_params) {
208*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
209*042d53a7SEvalZero     }
210*042d53a7SEvalZero 
211*042d53a7SEvalZero     ble_hs_id_set_pub(ack_params);
212*042d53a7SEvalZero     return 0;
213*042d53a7SEvalZero }
214*042d53a7SEvalZero 
215*042d53a7SEvalZero static int
ble_hs_startup_le_set_evmask_tx(void)216*042d53a7SEvalZero ble_hs_startup_le_set_evmask_tx(void)
217*042d53a7SEvalZero {
218*042d53a7SEvalZero     uint8_t buf[BLE_HCI_SET_LE_EVENT_MASK_LEN];
219*042d53a7SEvalZero     uint8_t version;
220*042d53a7SEvalZero     uint64_t mask;
221*042d53a7SEvalZero     int rc;
222*042d53a7SEvalZero 
223*042d53a7SEvalZero     version = ble_hs_hci_get_hci_version();
224*042d53a7SEvalZero 
225*042d53a7SEvalZero     /* TODO should we also check for supported commands when setting this? */
226*042d53a7SEvalZero 
227*042d53a7SEvalZero     /**
228*042d53a7SEvalZero      * Enable the following LE events:
229*042d53a7SEvalZero      *     0x0000000000000001 LE Connection Complete Event
230*042d53a7SEvalZero      *     0x0000000000000002 LE Advertising Report Event
231*042d53a7SEvalZero      *     0x0000000000000004 LE Connection Update Complete Event
232*042d53a7SEvalZero      *     0x0000000000000008 LE Read Remote Used Features Complete Event
233*042d53a7SEvalZero      *     0x0000000000000010 LE Long Term Key Request Event
234*042d53a7SEvalZero      */
235*042d53a7SEvalZero     mask = 0x000000000000001f;
236*042d53a7SEvalZero 
237*042d53a7SEvalZero     if (version >= BLE_HCI_VER_BCS_4_1) {
238*042d53a7SEvalZero         /**
239*042d53a7SEvalZero          * Enable the following LE events:
240*042d53a7SEvalZero          *   0x0000000000000020 LE Remote Connection Parameter Request Event */
241*042d53a7SEvalZero         mask |= 0x0000000000000020;
242*042d53a7SEvalZero     }
243*042d53a7SEvalZero 
244*042d53a7SEvalZero     if (version >= BLE_HCI_VER_BCS_4_2) {
245*042d53a7SEvalZero         /**
246*042d53a7SEvalZero          * Enable the following LE events:
247*042d53a7SEvalZero          *   0x0000000000000040 LE Data Length Change Event
248*042d53a7SEvalZero          *   0x0000000000000200 LE Enhanced Connection Complete Event
249*042d53a7SEvalZero          *   0x0000000000000400 LE Directed Advertising Report Event
250*042d53a7SEvalZero          */
251*042d53a7SEvalZero         mask |= 0x0000000000000640;
252*042d53a7SEvalZero     }
253*042d53a7SEvalZero 
254*042d53a7SEvalZero     if (version >= BLE_HCI_VER_BCS_5_0) {
255*042d53a7SEvalZero         /**
256*042d53a7SEvalZero          * Enable the following LE events:
257*042d53a7SEvalZero          *   0x0000000000000800 LE PHY Update Complete Event
258*042d53a7SEvalZero          *   0x0000000000001000 LE Extended Advertising Report Event
259*042d53a7SEvalZero          *   0x0000000000010000 LE Extended Scan Timeout Event
260*042d53a7SEvalZero          *   0x0000000000020000 LE Extended Advertising Set Terminated Event
261*042d53a7SEvalZero          *   0x0000000000040000 LE Scan Request Received Event
262*042d53a7SEvalZero          *   0x0000000000080000 LE Channel Selection Algorithm Event
263*042d53a7SEvalZero          */
264*042d53a7SEvalZero         mask |= 0x00000000000f1800;
265*042d53a7SEvalZero     }
266*042d53a7SEvalZero 
267*042d53a7SEvalZero     ble_hs_hci_cmd_build_le_set_event_mask(mask, buf, sizeof buf);
268*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
269*042d53a7SEvalZero                                                 BLE_HCI_OCF_LE_SET_EVENT_MASK),
270*042d53a7SEvalZero                                      buf, sizeof(buf));
271*042d53a7SEvalZero     if (rc != 0) {
272*042d53a7SEvalZero         return rc;
273*042d53a7SEvalZero     }
274*042d53a7SEvalZero 
275*042d53a7SEvalZero     return 0;
276*042d53a7SEvalZero }
277*042d53a7SEvalZero 
278*042d53a7SEvalZero static int
ble_hs_startup_set_evmask_tx(void)279*042d53a7SEvalZero ble_hs_startup_set_evmask_tx(void)
280*042d53a7SEvalZero {
281*042d53a7SEvalZero     uint8_t buf[BLE_HCI_SET_EVENT_MASK_LEN];
282*042d53a7SEvalZero     uint8_t version;
283*042d53a7SEvalZero     int rc;
284*042d53a7SEvalZero 
285*042d53a7SEvalZero     version = ble_hs_hci_get_hci_version();
286*042d53a7SEvalZero 
287*042d53a7SEvalZero     /**
288*042d53a7SEvalZero      * Enable the following events:
289*042d53a7SEvalZero      *     0x0000000000000010 Disconnection Complete Event
290*042d53a7SEvalZero      *     0x0000000000000080 Encryption Change Event
291*042d53a7SEvalZero      *     0x0000000000008000 Hardware Error Event
292*042d53a7SEvalZero      *     0x0000000002000000 Data Buffer Overflow Event
293*042d53a7SEvalZero      *     0x0000800000000000 Encryption Key Refresh Complete Event
294*042d53a7SEvalZero      *     0x2000000000000000 LE Meta-Event
295*042d53a7SEvalZero      */
296*042d53a7SEvalZero     ble_hs_hci_cmd_build_set_event_mask(0x2000800002008090, buf, sizeof buf);
297*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
298*042d53a7SEvalZero                                                 BLE_HCI_OCF_CB_SET_EVENT_MASK),
299*042d53a7SEvalZero                                      buf, sizeof(buf));
300*042d53a7SEvalZero     if (rc != 0) {
301*042d53a7SEvalZero         return rc;
302*042d53a7SEvalZero     }
303*042d53a7SEvalZero 
304*042d53a7SEvalZero     if (version >= BLE_HCI_VER_BCS_4_1) {
305*042d53a7SEvalZero         /**
306*042d53a7SEvalZero          * Enable the following events:
307*042d53a7SEvalZero          *     0x0000000000800000 Authenticated Payload Timeout Event
308*042d53a7SEvalZero          */
309*042d53a7SEvalZero         ble_hs_hci_cmd_build_set_event_mask2(0x0000000000800000, buf, sizeof buf);
310*042d53a7SEvalZero         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
311*042d53a7SEvalZero                                                     BLE_HCI_OCF_CB_SET_EVENT_MASK2),
312*042d53a7SEvalZero                                          buf, sizeof(buf));
313*042d53a7SEvalZero         if (rc != 0) {
314*042d53a7SEvalZero             return rc;
315*042d53a7SEvalZero         }
316*042d53a7SEvalZero     }
317*042d53a7SEvalZero 
318*042d53a7SEvalZero     return 0;
319*042d53a7SEvalZero }
320*042d53a7SEvalZero 
321*042d53a7SEvalZero static int
ble_hs_startup_reset_tx(void)322*042d53a7SEvalZero ble_hs_startup_reset_tx(void)
323*042d53a7SEvalZero {
324*042d53a7SEvalZero     int rc;
325*042d53a7SEvalZero 
326*042d53a7SEvalZero     rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
327*042d53a7SEvalZero                                                 BLE_HCI_OCF_CB_RESET),
328*042d53a7SEvalZero                                      NULL, 0);
329*042d53a7SEvalZero     if (rc != 0) {
330*042d53a7SEvalZero         return rc;
331*042d53a7SEvalZero     }
332*042d53a7SEvalZero 
333*042d53a7SEvalZero     return 0;
334*042d53a7SEvalZero }
335*042d53a7SEvalZero 
336*042d53a7SEvalZero int
ble_hs_startup_go(void)337*042d53a7SEvalZero ble_hs_startup_go(void)
338*042d53a7SEvalZero {
339*042d53a7SEvalZero     int rc;
340*042d53a7SEvalZero 
341*042d53a7SEvalZero     rc = ble_hs_startup_reset_tx();
342*042d53a7SEvalZero     if (rc != 0) {
343*042d53a7SEvalZero         return rc;
344*042d53a7SEvalZero     }
345*042d53a7SEvalZero 
346*042d53a7SEvalZero     rc = ble_hs_startup_read_local_ver_tx();
347*042d53a7SEvalZero     if (rc != 0) {
348*042d53a7SEvalZero         return rc;
349*042d53a7SEvalZero     }
350*042d53a7SEvalZero 
351*042d53a7SEvalZero     /* XXX: Read local supported commands. */
352*042d53a7SEvalZero 
353*042d53a7SEvalZero     /* we need to check this only if using external controller */
354*042d53a7SEvalZero #if !MYNEWT_VAL(BLE_DEVICE)
355*042d53a7SEvalZero     if (ble_hs_hci_get_hci_version() < BLE_HCI_VER_BCS_4_0) {
356*042d53a7SEvalZero         BLE_HS_LOG(ERROR, "Required controller version is 4.0 (6)\n");
357*042d53a7SEvalZero         return BLE_HS_ECONTROLLER;
358*042d53a7SEvalZero     }
359*042d53a7SEvalZero 
360*042d53a7SEvalZero     rc = ble_hs_startup_read_sup_f_tx();
361*042d53a7SEvalZero     if (rc != 0) {
362*042d53a7SEvalZero         return rc;
363*042d53a7SEvalZero     }
364*042d53a7SEvalZero #endif
365*042d53a7SEvalZero 
366*042d53a7SEvalZero     rc = ble_hs_startup_set_evmask_tx();
367*042d53a7SEvalZero     if (rc != 0) {
368*042d53a7SEvalZero         return rc;
369*042d53a7SEvalZero     }
370*042d53a7SEvalZero 
371*042d53a7SEvalZero     rc = ble_hs_startup_le_set_evmask_tx();
372*042d53a7SEvalZero     if (rc != 0) {
373*042d53a7SEvalZero         return rc;
374*042d53a7SEvalZero     }
375*042d53a7SEvalZero 
376*042d53a7SEvalZero     rc = ble_hs_startup_read_buf_sz();
377*042d53a7SEvalZero     if (rc != 0) {
378*042d53a7SEvalZero         return rc;
379*042d53a7SEvalZero     }
380*042d53a7SEvalZero 
381*042d53a7SEvalZero     rc = ble_hs_startup_le_read_sup_f_tx();
382*042d53a7SEvalZero     if (rc != 0) {
383*042d53a7SEvalZero         return rc;
384*042d53a7SEvalZero     }
385*042d53a7SEvalZero 
386*042d53a7SEvalZero     rc = ble_hs_startup_read_bd_addr();
387*042d53a7SEvalZero     if (rc != 0) {
388*042d53a7SEvalZero         return rc;
389*042d53a7SEvalZero     }
390*042d53a7SEvalZero 
391*042d53a7SEvalZero     ble_hs_pvcy_set_our_irk(NULL);
392*042d53a7SEvalZero 
393*042d53a7SEvalZero     /* If flow control is enabled, configure the controller to use it. */
394*042d53a7SEvalZero     ble_hs_flow_startup();
395*042d53a7SEvalZero 
396*042d53a7SEvalZero     return 0;
397*042d53a7SEvalZero }
398