• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <stddef.h>
21 #include <string.h>
22 #include "host/ble_hs.h"
23 #include "host/ble_hs_hci.h"
24 #include "ble_hs_priv.h"
25 
26 #if !MYNEWT_VAL(BLE_CONTROLLER)
ble_hs_startup_read_sup_f_tx(void)27 static int ble_hs_startup_read_sup_f_tx(void)
28 {
29     struct ble_hci_ip_rd_loc_supp_feat_rp rsp;
30     int rc;
31     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
32                                       BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT),
33                            NULL, 0, &rsp, sizeof(rsp));
34     if (rc != 0) {
35         return rc;
36     }
37 
38     /* for now we don't use it outside of init sequence so check this here
39      * LE Supported (Controller) byte 4, bit 6
40      */
41     if (!(rsp.features & 0x0000006000000000)) {
42         BLE_HS_LOG(ERROR, "Controller doesn't support LE\n");
43         return BLE_HS_ECONTROLLER;
44     }
45 
46     return 0;
47 }
48 #endif
49 
ble_hs_startup_read_local_ver_tx(void)50 static int ble_hs_startup_read_local_ver_tx(void)
51 {
52     struct ble_hci_ip_rd_local_ver_rp rsp;
53     int rc;
54     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
55                                       BLE_HCI_OCF_IP_RD_LOCAL_VER),
56                            NULL, 0, &rsp, sizeof(rsp));
57     if (rc != 0) {
58         return rc;
59     }
60 
61     /* For now we are interested only in HCI Version */
62     ble_hs_hci_set_hci_version(rsp.hci_ver);
63     return 0;
64 }
65 
ble_hs_startup_le_read_sup_f_tx(void)66 static int ble_hs_startup_le_read_sup_f_tx(void)
67 {
68     struct ble_hci_le_rd_loc_supp_feat_rp rsp;
69     int rc;
70     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
71                                       BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT),
72                            NULL, 0, &rsp, sizeof(rsp));
73     if (rc != 0) {
74         return rc;
75     }
76 
77     ble_hs_hci_set_le_supported_feat(le64toh(rsp.features));
78     return 0;
79 }
80 
ble_hs_startup_le_read_buf_sz_tx(uint16_t * out_pktlen,uint8_t * out_max_pkts)81 static int ble_hs_startup_le_read_buf_sz_tx(uint16_t *out_pktlen, uint8_t *out_max_pkts)
82 {
83     struct ble_hci_le_rd_buf_size_rp rsp;
84     int rc;
85     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE), NULL, 0,
86                            &rsp, sizeof(rsp));
87     if (rc != 0) {
88         return rc;
89     }
90 
91     *out_pktlen = le16toh(rsp.data_len);
92     *out_max_pkts = rsp.data_packets;
93     return 0;
94 }
95 
ble_hs_startup_read_buf_sz_tx(uint16_t * out_pktlen,uint16_t * out_max_pkts)96 static int ble_hs_startup_read_buf_sz_tx(uint16_t *out_pktlen, uint16_t *out_max_pkts)
97 {
98     struct ble_hci_ip_rd_buf_size_rp rsp;
99     int rc;
100     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BUF_SIZE), NULL, 0,
101                            &rsp, sizeof(rsp));
102     if (rc != 0) {
103         return rc;
104     }
105 
106     *out_pktlen = le16toh(rsp.acl_data_len);
107     *out_max_pkts = le16toh(rsp.acl_num);
108     return 0;
109 }
110 
ble_hs_startup_read_buf_sz(void)111 static int ble_hs_startup_read_buf_sz(void)
112 {
113     uint16_t le_pktlen = 0;
114     uint16_t max_pkts = 0;
115     uint16_t pktlen = 0;
116     uint8_t le_max_pkts = 0;
117     int rc;
118     rc = ble_hs_startup_le_read_buf_sz_tx(&le_pktlen, &le_max_pkts);
119     if (rc != 0) {
120         return rc;
121     }
122 
123     if (le_pktlen != 0) {
124         pktlen = le_pktlen;
125         max_pkts = le_max_pkts;
126     } else {
127         rc = ble_hs_startup_read_buf_sz_tx(&pktlen, &max_pkts);
128         if (rc != 0) {
129             return rc;
130         }
131     }
132 
133     rc = ble_hs_hci_set_buf_sz(pktlen, max_pkts);
134     if (rc != 0) {
135         return rc;
136     }
137 
138     return 0;
139 }
140 
ble_hs_startup_read_bd_addr(void)141 static int ble_hs_startup_read_bd_addr(void)
142 {
143     struct ble_hci_ip_rd_bd_addr_rp rsp;
144     int rc;
145     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
146                                       BLE_HCI_OCF_IP_RD_BD_ADDR),
147                            NULL, 0, &rsp, sizeof(rsp));
148     if (rc != 0) {
149         return rc;
150     }
151 
152     ble_hs_id_set_pub(rsp.addr);
153     return 0;
154 }
155 
ble_hs_startup_le_set_evmask_tx(void)156 static int ble_hs_startup_le_set_evmask_tx(void)
157 {
158     struct ble_hci_le_set_event_mask_cp cmd;
159     uint8_t version;
160     uint64_t mask;
161     int rc;
162     version = ble_hs_hci_get_hci_version();
163     /* should we also check for supported commands when setting this? */
164     /**
165      * Enable the following LE events:
166      *     0x0000000000000001 LE Connection Complete Event
167      *     0x0000000000000002 LE Advertising Report Event
168      *     0x0000000000000004 LE Connection Update Complete Event
169      *     0x0000000000000008 LE Read Remote Used Features Complete Event
170      *     0x0000000000000010 LE Long Term Key Request Event
171      */
172     mask = 0x000000000000001f;
173 
174     if (version >= BLE_HCI_VER_BCS_4_1) {
175         /**
176          * Enable the following LE events:
177          *   0x0000000000000020 LE Remote Connection Parameter Request Event */
178         mask |= 0x0000000000000020;
179     }
180 
181     if (version >= BLE_HCI_VER_BCS_4_2) {
182         /**
183          * Enable the following LE events:
184          *   0x0000000000000040 LE Data Length Change Event
185          *   0x0000000000000200 LE Enhanced Connection Complete Event
186          *   0x0000000000000400 LE Directed Advertising Report Event
187          */
188         mask |= 0x0000000000000640;
189     }
190 
191     if (version >= BLE_HCI_VER_BCS_5_0) {
192         /**
193          * Enable the following LE events:
194          *   0x0000000000000800 LE PHY Update Complete Event
195          *   0x0000000000001000 LE Extended Advertising Report Event
196          *   0x0000000000002000 LE Periodic Advertising Sync Established Event
197          *   0x0000000000004000 LE Periodic Advertising Report Event
198          *   0x0000000000008000 LE Periodic Advertising Sync Lost Event
199          *   0x0000000000010000 LE Extended Scan Timeout Event
200          *   0x0000000000020000 LE Extended Advertising Set Terminated Event
201          *   0x0000000000040000 LE Scan Request Received Event
202          *   0x0000000000080000 LE Channel Selection Algorithm Event
203          */
204         mask |= 0x00000000000ff800;
205     }
206 
207 #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER)
208 
209     if (version >= BLE_HCI_VER_BCS_5_1) {
210         /**
211          * Enable the following LE events:
212          * 0x0000000000800000 LE Periodic Advertising Sync Transfer Received event
213          */
214         mask |= 0x0000000000800000;
215     }
216 
217 #endif
218     cmd.event_mask = htole64(mask);
219     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
220                                       BLE_HCI_OCF_LE_SET_EVENT_MASK),
221                            &cmd, sizeof(cmd), NULL, 0);
222     if (rc != 0) {
223         return rc;
224     }
225 
226     return 0;
227 }
228 
ble_hs_startup_set_evmask_tx(void)229 static int ble_hs_startup_set_evmask_tx(void)
230 {
231     struct ble_hci_cb_set_event_mask_cp cmd;
232     struct ble_hci_cb_set_event_mask2_cp cmd2;
233     uint8_t version;
234     int rc;
235     version = ble_hs_hci_get_hci_version();
236     /**
237      * Enable the following events:
238      *     0x0000000000000010 Disconnection Complete Event
239      *     0x0000000000000080 Encryption Change Event
240      *     0x0000000000008000 Hardware Error Event
241      *     0x0000000002000000 Data Buffer Overflow Event
242      *     0x0000800000000000 Encryption Key Refresh Complete Event
243      *     0x2000000000000000 LE Meta-Event
244      */
245     cmd.event_mask = htole64(0x2000800002008090);
246     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
247                                       BLE_HCI_OCF_CB_SET_EVENT_MASK),
248                            &cmd, sizeof(cmd), NULL, 0);
249     if (rc != 0) {
250         return rc;
251     }
252 
253     if (version >= BLE_HCI_VER_BCS_4_1) {
254         /**
255          * Enable the following events:
256          *     0x0000000000800000 Authenticated Payload Timeout Event
257          */
258         cmd2.event_mask2 = htole64(0x0000000000800000);
259         rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
260                                           BLE_HCI_OCF_CB_SET_EVENT_MASK2),
261                                &cmd2, sizeof(cmd2), NULL, 0);
262         if (rc != 0) {
263             return rc;
264         }
265     }
266 
267     return 0;
268 }
269 
ble_hs_startup_reset_tx(void)270 static int ble_hs_startup_reset_tx(void)
271 {
272     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
273                                         BLE_HCI_OCF_CB_RESET),
274                              NULL, 0, NULL, 0);
275 }
276 
ble_hs_startup_go(void)277 int ble_hs_startup_go(void)
278 {
279     int rc;
280     rc = ble_hs_startup_reset_tx();
281     if (rc != 0) {
282         return rc;
283     }
284 
285     rc = ble_hs_startup_read_local_ver_tx();
286     if (rc != 0) {
287         return rc;
288     }
289 
290     /* XXX: Read local supported commands. */
291     /* we need to check this only if using external controller */
292 #if !MYNEWT_VAL(BLE_CONTROLLER)
293 
294     if (ble_hs_hci_get_hci_version() < BLE_HCI_VER_BCS_4_0) {
295         BLE_HS_LOG(ERROR, "Required controller version is 4.0 (6)\n");
296         return BLE_HS_ECONTROLLER;
297     }
298 
299     rc = ble_hs_startup_read_sup_f_tx();
300     if (rc != 0) {
301         return rc;
302     }
303 
304 #endif
305     rc = ble_hs_startup_set_evmask_tx();
306     if (rc != 0) {
307         return rc;
308     }
309 
310     rc = ble_hs_startup_le_set_evmask_tx();
311     if (rc != 0) {
312         return rc;
313     }
314 
315     rc = ble_hs_startup_read_buf_sz();
316     if (rc != 0) {
317         return rc;
318     }
319 
320     rc = ble_hs_startup_le_read_sup_f_tx();
321     if (rc != 0) {
322         return rc;
323     }
324 
325     rc = ble_hs_startup_read_bd_addr();
326     if (rc != 0) {
327         return rc;
328     }
329 
330     rc = ble_hs_pvcy_set_our_irk(NULL);
331     if (rc != 0) {
332         assert(0);
333         return rc;
334     }
335 
336     /* If flow control is enabled, configure the controller to use it. */
337     ble_hs_flow_startup();
338     return 0;
339 }