xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/controller/src/ble_ll.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 <stdint.h>
21*042d53a7SEvalZero #include <stdlib.h>
22*042d53a7SEvalZero #include <assert.h>
23*042d53a7SEvalZero #include <string.h>
24*042d53a7SEvalZero #include "sysinit/sysinit.h"
25*042d53a7SEvalZero #include "syscfg/syscfg.h"
26*042d53a7SEvalZero #include "os/os.h"
27*042d53a7SEvalZero #include "os/os_cputime.h"
28*042d53a7SEvalZero #include "stats/stats.h"
29*042d53a7SEvalZero #include "nimble/ble.h"
30*042d53a7SEvalZero #include "nimble/nimble_opt.h"
31*042d53a7SEvalZero #include "nimble/hci_common.h"
32*042d53a7SEvalZero #include "nimble/ble_hci_trans.h"
33*042d53a7SEvalZero #include "controller/ble_hw.h"
34*042d53a7SEvalZero #include "controller/ble_phy.h"
35*042d53a7SEvalZero #include "controller/ble_phy_trace.h"
36*042d53a7SEvalZero #include "controller/ble_ll.h"
37*042d53a7SEvalZero #include "controller/ble_ll_adv.h"
38*042d53a7SEvalZero #include "controller/ble_ll_sched.h"
39*042d53a7SEvalZero #include "controller/ble_ll_scan.h"
40*042d53a7SEvalZero #include "controller/ble_ll_hci.h"
41*042d53a7SEvalZero #include "controller/ble_ll_whitelist.h"
42*042d53a7SEvalZero #include "controller/ble_ll_resolv.h"
43*042d53a7SEvalZero #include "controller/ble_ll_xcvr.h"
44*042d53a7SEvalZero #include "controller/ble_ll_trace.h"
45*042d53a7SEvalZero #include "ble_ll_conn_priv.h"
46*042d53a7SEvalZero 
47*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
48*042d53a7SEvalZero #include "ble_ll_dtm_priv.h"
49*042d53a7SEvalZero #endif
50*042d53a7SEvalZero 
51*042d53a7SEvalZero /* XXX:
52*042d53a7SEvalZero  *
53*042d53a7SEvalZero  * 1) use the sanity task!
54*042d53a7SEvalZero  * 2) Need to figure out what to do with packets that we hand up that did
55*042d53a7SEvalZero  * not pass the filter policy for the given state. Currently I count all
56*042d53a7SEvalZero  * packets I think. Need to figure out what to do with this.
57*042d53a7SEvalZero  * 3) For the features defined, we need to conditionally compile code.
58*042d53a7SEvalZero  * 4) Should look into always disabled the wfr interrupt if we receive the
59*042d53a7SEvalZero  * start of a frame. Need to look at the various states to see if this is the
60*042d53a7SEvalZero  * right thing to do.
61*042d53a7SEvalZero  */
62*042d53a7SEvalZero 
63*042d53a7SEvalZero /* Supported states */
64*042d53a7SEvalZero #define BLE_LL_S_NCA                    (0x00000000001)
65*042d53a7SEvalZero #define BLE_LL_S_SA                     (0x00000000002)
66*042d53a7SEvalZero #define BLE_LL_S_CA                     (0x00000000004)
67*042d53a7SEvalZero #define BLE_LL_S_HDCA                   (0x00000000008)
68*042d53a7SEvalZero #define BLE_LL_S_PS                     (0x00000000010)
69*042d53a7SEvalZero #define BLE_LL_S_AS                     (0x00000000020)
70*042d53a7SEvalZero #define BLE_LL_S_INIT                   (0x00000000040)
71*042d53a7SEvalZero #define BLE_LL_S_SLAVE                  (0x00000000080)
72*042d53a7SEvalZero #define BLE_LL_S_NCA_PS                 (0x00000000100)
73*042d53a7SEvalZero #define BLE_LL_S_SA_PS                  (0x00000000200)
74*042d53a7SEvalZero #define BLE_LL_S_CA_PS                  (0x00000000400)
75*042d53a7SEvalZero #define BLE_LL_S_HDCA_PS                (0x00000000800)
76*042d53a7SEvalZero #define BLE_LL_S_NCA_AS                 (0x00000001000)
77*042d53a7SEvalZero #define BLE_LL_S_SA_AS                  (0x00000002000)
78*042d53a7SEvalZero #define BLE_LL_S_CA_AS                  (0x00000004000)
79*042d53a7SEvalZero #define BLE_LL_S_HDCA_AS                (0x00000008000)
80*042d53a7SEvalZero #define BLE_LL_S_NCA_INIT               (0x00000010000)
81*042d53a7SEvalZero #define BLE_LL_S_SA_INIT                (0x00000020000)
82*042d53a7SEvalZero #define BLE_LL_S_NCA_MASTER             (0x00000040000)
83*042d53a7SEvalZero #define BLE_LL_S_SA_MASTER              (0x00000080000)
84*042d53a7SEvalZero #define BLE_LL_S_NCA_SLAVE              (0x00000100000)
85*042d53a7SEvalZero #define BLE_LL_S_SA_SLAVE               (0x00000200000)
86*042d53a7SEvalZero #define BLE_LL_S_PS_INIT                (0x00000400000)
87*042d53a7SEvalZero #define BLE_LL_S_AS_INIT                (0x00000800000)
88*042d53a7SEvalZero #define BLE_LL_S_PS_MASTER              (0x00001000000)
89*042d53a7SEvalZero #define BLE_LL_S_AS_MASTER              (0x00002000000)
90*042d53a7SEvalZero #define BLE_LL_S_PS_SLAVE               (0x00004000000)
91*042d53a7SEvalZero #define BLE_LL_S_AS_SLAVE               (0x00008000000)
92*042d53a7SEvalZero #define BLE_LL_S_INIT_MASTER            (0x00010000000)
93*042d53a7SEvalZero #define BLE_LL_S_LDCA                   (0x00020000000)
94*042d53a7SEvalZero #define BLE_LL_S_LDCA_PS                (0x00040000000)
95*042d53a7SEvalZero #define BLE_LL_S_LDCA_AS                (0x00080000000)
96*042d53a7SEvalZero #define BLE_LL_S_CA_INIT                (0x00100000000)
97*042d53a7SEvalZero #define BLE_LL_S_HDCA_INIT              (0x00200000000)
98*042d53a7SEvalZero #define BLE_LL_S_LDCA_INIT              (0x00400000000)
99*042d53a7SEvalZero #define BLE_LL_S_CA_MASTER              (0x00800000000)
100*042d53a7SEvalZero #define BLE_LL_S_HDCA_MASTER            (0x01000000000)
101*042d53a7SEvalZero #define BLE_LL_S_LDCA_MASTER            (0x02000000000)
102*042d53a7SEvalZero #define BLE_LL_S_CA_SLAVE               (0x04000000000)
103*042d53a7SEvalZero #define BLE_LL_S_HDCA_SLAVE             (0x08000000000)
104*042d53a7SEvalZero #define BLE_LL_S_LDCA_SLAVE             (0x10000000000)
105*042d53a7SEvalZero #define BLE_LL_S_INIT_SLAVE             (0x20000000000)
106*042d53a7SEvalZero 
107*042d53a7SEvalZero #define BLE_LL_SUPPORTED_STATES             \
108*042d53a7SEvalZero (                                           \
109*042d53a7SEvalZero     BLE_LL_S_NCA                    |       \
110*042d53a7SEvalZero     BLE_LL_S_SA                     |       \
111*042d53a7SEvalZero     BLE_LL_S_CA                     |       \
112*042d53a7SEvalZero     BLE_LL_S_HDCA                   |       \
113*042d53a7SEvalZero     BLE_LL_S_PS                     |       \
114*042d53a7SEvalZero     BLE_LL_S_AS                     |       \
115*042d53a7SEvalZero     BLE_LL_S_INIT                   |       \
116*042d53a7SEvalZero     BLE_LL_S_SLAVE                  |       \
117*042d53a7SEvalZero     BLE_LL_S_NCA_PS                 |       \
118*042d53a7SEvalZero     BLE_LL_S_SA_PS                  |       \
119*042d53a7SEvalZero     BLE_LL_S_CA_PS                  |       \
120*042d53a7SEvalZero     BLE_LL_S_HDCA_PS                |       \
121*042d53a7SEvalZero     BLE_LL_S_NCA_AS                 |       \
122*042d53a7SEvalZero     BLE_LL_S_SA_AS                  |       \
123*042d53a7SEvalZero     BLE_LL_S_CA_AS                  |       \
124*042d53a7SEvalZero     BLE_LL_S_HDCA_AS                |       \
125*042d53a7SEvalZero     BLE_LL_S_NCA_INIT               |       \
126*042d53a7SEvalZero     BLE_LL_S_SA_INIT                |       \
127*042d53a7SEvalZero     BLE_LL_S_NCA_MASTER             |       \
128*042d53a7SEvalZero     BLE_LL_S_SA_MASTER              |       \
129*042d53a7SEvalZero     BLE_LL_S_NCA_SLAVE              |       \
130*042d53a7SEvalZero     BLE_LL_S_SA_SLAVE               |       \
131*042d53a7SEvalZero     BLE_LL_S_PS_INIT                |       \
132*042d53a7SEvalZero     BLE_LL_S_AS_INIT                |       \
133*042d53a7SEvalZero     BLE_LL_S_PS_MASTER              |       \
134*042d53a7SEvalZero     BLE_LL_S_AS_MASTER              |       \
135*042d53a7SEvalZero     BLE_LL_S_PS_SLAVE               |       \
136*042d53a7SEvalZero     BLE_LL_S_AS_SLAVE               |       \
137*042d53a7SEvalZero     BLE_LL_S_INIT_MASTER            |       \
138*042d53a7SEvalZero     BLE_LL_S_LDCA                   |       \
139*042d53a7SEvalZero     BLE_LL_S_LDCA_PS                |       \
140*042d53a7SEvalZero     BLE_LL_S_LDCA_AS                |       \
141*042d53a7SEvalZero     BLE_LL_S_CA_INIT                |       \
142*042d53a7SEvalZero     BLE_LL_S_HDCA_INIT              |       \
143*042d53a7SEvalZero     BLE_LL_S_LDCA_INIT              |       \
144*042d53a7SEvalZero     BLE_LL_S_CA_MASTER              |       \
145*042d53a7SEvalZero     BLE_LL_S_HDCA_MASTER            |       \
146*042d53a7SEvalZero     BLE_LL_S_LDCA_MASTER            |       \
147*042d53a7SEvalZero     BLE_LL_S_CA_SLAVE               |       \
148*042d53a7SEvalZero     BLE_LL_S_HDCA_SLAVE             |       \
149*042d53a7SEvalZero     BLE_LL_S_LDCA_SLAVE             |       \
150*042d53a7SEvalZero     BLE_LL_S_INIT_SLAVE)
151*042d53a7SEvalZero 
152*042d53a7SEvalZero /* The global BLE LL data object */
153*042d53a7SEvalZero struct ble_ll_obj g_ble_ll_data;
154*042d53a7SEvalZero 
155*042d53a7SEvalZero /* Global link layer statistics */
156*042d53a7SEvalZero STATS_SECT_DECL(ble_ll_stats) ble_ll_stats;
157*042d53a7SEvalZero STATS_NAME_START(ble_ll_stats)
158*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, hci_cmds)
159*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, hci_cmd_errs)
160*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, hci_events_sent)
161*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, bad_ll_state)
162*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, bad_acl_hdr)
163*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, no_bufs)
164*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_pdu_crc_ok)
165*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_pdu_crc_err)
166*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_bytes_crc_ok)
167*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_bytes_crc_err)
168*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_data_pdu_crc_ok)
169*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_data_pdu_crc_err)
170*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_data_bytes_crc_ok)
171*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_data_bytes_crc_err)
172*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_malformed_pkts)
173*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_ind)
174*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_direct_ind)
175*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_nonconn_ind)
176*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_adv_ext_ind)
177*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_scan_reqs)
178*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_scan_rsps)
179*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_connect_reqs)
180*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_scan_ind)
181*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, rx_aux_connect_rsp)
182*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, adv_txg)
183*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, adv_late_starts)
184*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, adv_resched_pdu_fail)
185*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, adv_drop_event)
186*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, sched_state_conn_errs)
187*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, sched_state_adv_errs)
188*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_starts)
189*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_stops)
190*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_req_txf)
191*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_req_txg)
192*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_rsp_txg)
193*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_missed_adv)
194*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_scheduled)
195*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_received)
196*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_fired_for_read)
197*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_allocated)
198*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_freed)
199*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_sched_cb)
200*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_conn_req_tx)
201*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_conn_rsp_tx)
202*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_conn_rsp_err)
203*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_scan_req_tx)
204*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_scan_rsp_err)
205*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_chain_cnt)
206*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, aux_chain_err)
207*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, adv_evt_dropped)
208*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_timer_stopped)
209*042d53a7SEvalZero     STATS_NAME(ble_ll_stats, scan_timer_restarted)
210*042d53a7SEvalZero STATS_NAME_END(ble_ll_stats)
211*042d53a7SEvalZero 
212*042d53a7SEvalZero static void ble_ll_event_rx_pkt(struct ble_npl_event *ev);
213*042d53a7SEvalZero static void ble_ll_event_tx_pkt(struct ble_npl_event *ev);
214*042d53a7SEvalZero static void ble_ll_event_dbuf_overflow(struct ble_npl_event *ev);
215*042d53a7SEvalZero 
216*042d53a7SEvalZero #if MYNEWT
217*042d53a7SEvalZero 
218*042d53a7SEvalZero /* The BLE LL task data structure */
219*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
220*042d53a7SEvalZero /* TODO: This is for testing. Check it we really need it */
221*042d53a7SEvalZero #define BLE_LL_STACK_SIZE   (128)
222*042d53a7SEvalZero #else
223*042d53a7SEvalZero #define BLE_LL_STACK_SIZE   (90)
224*042d53a7SEvalZero #endif
225*042d53a7SEvalZero 
226*042d53a7SEvalZero struct os_task g_ble_ll_task;
227*042d53a7SEvalZero 
228*042d53a7SEvalZero OS_TASK_STACK_DEFINE(g_ble_ll_stack, BLE_LL_STACK_SIZE);
229*042d53a7SEvalZero 
230*042d53a7SEvalZero #endif /* MYNEWT */
231*042d53a7SEvalZero 
232*042d53a7SEvalZero /** Our global device address (public) */
233*042d53a7SEvalZero uint8_t g_dev_addr[BLE_DEV_ADDR_LEN];
234*042d53a7SEvalZero 
235*042d53a7SEvalZero /** Our random address */
236*042d53a7SEvalZero uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
237*042d53a7SEvalZero 
238*042d53a7SEvalZero static const uint16_t g_ble_ll_pdu_header_tx_time[BLE_PHY_NUM_MODE] =
239*042d53a7SEvalZero {
240*042d53a7SEvalZero     [BLE_PHY_MODE_1M] =
241*042d53a7SEvalZero             (BLE_LL_PREAMBLE_LEN + BLE_LL_ACC_ADDR_LEN + BLE_LL_CRC_LEN +
242*042d53a7SEvalZero                     BLE_LL_PDU_HDR_LEN) << 3,
243*042d53a7SEvalZero     [BLE_PHY_MODE_2M] =
244*042d53a7SEvalZero             (BLE_LL_PREAMBLE_LEN * 2 + BLE_LL_ACC_ADDR_LEN + BLE_LL_CRC_LEN +
245*042d53a7SEvalZero                     BLE_LL_PDU_HDR_LEN) << 2,
246*042d53a7SEvalZero     /* For Coded PHY we have exact TX times provided by specification:
247*042d53a7SEvalZero      * - Preamble, Access Address, CI, TERM1 (always coded as S=8)
248*042d53a7SEvalZero      * - PDU, CRC, TERM2 (coded as S=2 or S=8)
249*042d53a7SEvalZero      * (Vol 6, Part B, 2.2).
250*042d53a7SEvalZero      */
251*042d53a7SEvalZero     [BLE_PHY_MODE_CODED_125KBPS] =
252*042d53a7SEvalZero             (80 + 256 + 16 + 24 + 8 * (BLE_LL_PDU_HDR_LEN * 8 + 24 + 3)),
253*042d53a7SEvalZero     [BLE_PHY_MODE_CODED_500KBPS] =
254*042d53a7SEvalZero             (80 + 256 + 16 + 24 + 2 * (BLE_LL_PDU_HDR_LEN * 8 + 24 + 3)),
255*042d53a7SEvalZero };
256*042d53a7SEvalZero 
257*042d53a7SEvalZero /**
258*042d53a7SEvalZero  * Counts the number of advertising PDU's received, by type. For advertising
259*042d53a7SEvalZero  * PDU's that contain a destination address, we still count these packets even
260*042d53a7SEvalZero  * if they are not for us.
261*042d53a7SEvalZero  *
262*042d53a7SEvalZero  * @param pdu_type
263*042d53a7SEvalZero  */
264*042d53a7SEvalZero static void
ble_ll_count_rx_adv_pdus(uint8_t pdu_type)265*042d53a7SEvalZero ble_ll_count_rx_adv_pdus(uint8_t pdu_type)
266*042d53a7SEvalZero {
267*042d53a7SEvalZero     /* Count received packet types  */
268*042d53a7SEvalZero     switch (pdu_type) {
269*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_ADV_EXT_IND:
270*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_adv_ext_ind);
271*042d53a7SEvalZero         break;
272*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_ADV_IND:
273*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_adv_ind);
274*042d53a7SEvalZero         break;
275*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
276*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_adv_direct_ind);
277*042d53a7SEvalZero         break;
278*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
279*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_adv_nonconn_ind);
280*042d53a7SEvalZero         break;
281*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_SCAN_REQ:
282*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_scan_reqs);
283*042d53a7SEvalZero         break;
284*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_SCAN_RSP:
285*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_scan_rsps);
286*042d53a7SEvalZero         break;
287*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_CONNECT_REQ:
288*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_connect_reqs);
289*042d53a7SEvalZero         break;
290*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP:
291*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_aux_connect_rsp);
292*042d53a7SEvalZero         break;
293*042d53a7SEvalZero     case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
294*042d53a7SEvalZero         STATS_INC(ble_ll_stats, rx_scan_ind);
295*042d53a7SEvalZero         break;
296*042d53a7SEvalZero     default:
297*042d53a7SEvalZero         break;
298*042d53a7SEvalZero     }
299*042d53a7SEvalZero }
300*042d53a7SEvalZero 
301*042d53a7SEvalZero /**
302*042d53a7SEvalZero  * Allocate a pdu (chain) for reception.
303*042d53a7SEvalZero  *
304*042d53a7SEvalZero  * @param len
305*042d53a7SEvalZero  *
306*042d53a7SEvalZero  * @return struct os_mbuf*
307*042d53a7SEvalZero  */
308*042d53a7SEvalZero struct os_mbuf *
ble_ll_rxpdu_alloc(uint16_t len)309*042d53a7SEvalZero ble_ll_rxpdu_alloc(uint16_t len)
310*042d53a7SEvalZero {
311*042d53a7SEvalZero     uint16_t mb_bytes;
312*042d53a7SEvalZero     struct os_mbuf *m;
313*042d53a7SEvalZero     struct os_mbuf *n;
314*042d53a7SEvalZero     struct os_mbuf *p;
315*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
316*042d53a7SEvalZero 
317*042d53a7SEvalZero     p = os_msys_get_pkthdr(len, sizeof(struct ble_mbuf_hdr));
318*042d53a7SEvalZero     if (!p) {
319*042d53a7SEvalZero         goto rxpdu_alloc_exit;
320*042d53a7SEvalZero     }
321*042d53a7SEvalZero 
322*042d53a7SEvalZero     /* Set packet length */
323*042d53a7SEvalZero     pkthdr = OS_MBUF_PKTHDR(p);
324*042d53a7SEvalZero     pkthdr->omp_len = len;
325*042d53a7SEvalZero 
326*042d53a7SEvalZero     /*
327*042d53a7SEvalZero      * NOTE: first mbuf in chain will have data pre-pended to it so we adjust
328*042d53a7SEvalZero      * m_data by a word.
329*042d53a7SEvalZero      */
330*042d53a7SEvalZero     p->om_data += 4;
331*042d53a7SEvalZero     mb_bytes = (p->om_omp->omp_databuf_len - p->om_pkthdr_len - 4);
332*042d53a7SEvalZero 
333*042d53a7SEvalZero     if (mb_bytes < len) {
334*042d53a7SEvalZero         n = p;
335*042d53a7SEvalZero         len -= mb_bytes;
336*042d53a7SEvalZero         while (len) {
337*042d53a7SEvalZero             m = os_msys_get(len, 0);
338*042d53a7SEvalZero             if (!m) {
339*042d53a7SEvalZero                 os_mbuf_free_chain(p);
340*042d53a7SEvalZero                 p = NULL;
341*042d53a7SEvalZero                 goto rxpdu_alloc_exit;
342*042d53a7SEvalZero             }
343*042d53a7SEvalZero             /* Chain new mbuf to existing chain */
344*042d53a7SEvalZero             SLIST_NEXT(n, om_next) = m;
345*042d53a7SEvalZero             n = m;
346*042d53a7SEvalZero             mb_bytes = m->om_omp->omp_databuf_len;
347*042d53a7SEvalZero             if (mb_bytes >= len) {
348*042d53a7SEvalZero                 len = 0;
349*042d53a7SEvalZero             } else {
350*042d53a7SEvalZero                 len -= mb_bytes;
351*042d53a7SEvalZero             }
352*042d53a7SEvalZero         }
353*042d53a7SEvalZero     }
354*042d53a7SEvalZero 
355*042d53a7SEvalZero 
356*042d53a7SEvalZero rxpdu_alloc_exit:
357*042d53a7SEvalZero     if (!p) {
358*042d53a7SEvalZero         STATS_INC(ble_ll_stats, no_bufs);
359*042d53a7SEvalZero     }
360*042d53a7SEvalZero     return p;
361*042d53a7SEvalZero }
362*042d53a7SEvalZero 
363*042d53a7SEvalZero int
ble_ll_chk_txrx_octets(uint16_t octets)364*042d53a7SEvalZero ble_ll_chk_txrx_octets(uint16_t octets)
365*042d53a7SEvalZero {
366*042d53a7SEvalZero     int rc;
367*042d53a7SEvalZero 
368*042d53a7SEvalZero     if ((octets < BLE_LL_CONN_SUPP_BYTES_MIN) ||
369*042d53a7SEvalZero         (octets > BLE_LL_CONN_SUPP_BYTES_MAX)) {
370*042d53a7SEvalZero         rc = 0;
371*042d53a7SEvalZero     } else {
372*042d53a7SEvalZero         rc = 1;
373*042d53a7SEvalZero     }
374*042d53a7SEvalZero 
375*042d53a7SEvalZero     return rc;
376*042d53a7SEvalZero }
377*042d53a7SEvalZero 
378*042d53a7SEvalZero int
ble_ll_chk_txrx_time(uint16_t time)379*042d53a7SEvalZero ble_ll_chk_txrx_time(uint16_t time)
380*042d53a7SEvalZero {
381*042d53a7SEvalZero     int rc;
382*042d53a7SEvalZero 
383*042d53a7SEvalZero     if ((time < BLE_LL_CONN_SUPP_TIME_MIN) ||
384*042d53a7SEvalZero         (time > BLE_LL_CONN_SUPP_TIME_MAX)) {
385*042d53a7SEvalZero         rc = 0;
386*042d53a7SEvalZero     } else {
387*042d53a7SEvalZero         rc = 1;
388*042d53a7SEvalZero     }
389*042d53a7SEvalZero 
390*042d53a7SEvalZero     return rc;
391*042d53a7SEvalZero }
392*042d53a7SEvalZero 
393*042d53a7SEvalZero /**
394*042d53a7SEvalZero  * Checks to see if the address is a resolvable private address.
395*042d53a7SEvalZero  *
396*042d53a7SEvalZero  * NOTE: the addr_type parameter will be 0 if the address is public;
397*042d53a7SEvalZero  * any other value is random (all non-zero values).
398*042d53a7SEvalZero  *
399*042d53a7SEvalZero  * @param addr
400*042d53a7SEvalZero  * @param addr_type Public (zero) or Random (non-zero) address
401*042d53a7SEvalZero  *
402*042d53a7SEvalZero  * @return int
403*042d53a7SEvalZero  */
404*042d53a7SEvalZero int
ble_ll_is_rpa(uint8_t * addr,uint8_t addr_type)405*042d53a7SEvalZero ble_ll_is_rpa(uint8_t *addr, uint8_t addr_type)
406*042d53a7SEvalZero {
407*042d53a7SEvalZero     int rc;
408*042d53a7SEvalZero 
409*042d53a7SEvalZero     if (addr_type && ((addr[5] & 0xc0) == 0x40)) {
410*042d53a7SEvalZero         rc = 1;
411*042d53a7SEvalZero     } else {
412*042d53a7SEvalZero         rc = 0;
413*042d53a7SEvalZero     }
414*042d53a7SEvalZero     return rc;
415*042d53a7SEvalZero }
416*042d53a7SEvalZero 
417*042d53a7SEvalZero /* Checks to see that the device is a valid random address */
418*042d53a7SEvalZero int
ble_ll_is_valid_random_addr(uint8_t * addr)419*042d53a7SEvalZero ble_ll_is_valid_random_addr(uint8_t *addr)
420*042d53a7SEvalZero {
421*042d53a7SEvalZero     int i;
422*042d53a7SEvalZero     int rc;
423*042d53a7SEvalZero     uint16_t sum;
424*042d53a7SEvalZero     uint8_t addr_type;
425*042d53a7SEvalZero 
426*042d53a7SEvalZero     /* Make sure all bits are neither one nor zero */
427*042d53a7SEvalZero     sum = 0;
428*042d53a7SEvalZero     for (i = 0; i < (BLE_DEV_ADDR_LEN -1); ++i) {
429*042d53a7SEvalZero         sum += addr[i];
430*042d53a7SEvalZero     }
431*042d53a7SEvalZero     sum += addr[5] & 0x3f;
432*042d53a7SEvalZero 
433*042d53a7SEvalZero     if ((sum == 0) || (sum == ((5*255) + 0x3f))) {
434*042d53a7SEvalZero         return 0;
435*042d53a7SEvalZero     }
436*042d53a7SEvalZero 
437*042d53a7SEvalZero     /* Get the upper two bits of the address */
438*042d53a7SEvalZero     rc = 1;
439*042d53a7SEvalZero     addr_type = addr[5] & 0xc0;
440*042d53a7SEvalZero     if (addr_type == 0xc0) {
441*042d53a7SEvalZero         /* Static random address. No other checks needed */
442*042d53a7SEvalZero     } else if (addr_type == 0x40) {
443*042d53a7SEvalZero         /* Resolvable */
444*042d53a7SEvalZero         sum = addr[3] + addr[4] + (addr[5] & 0x3f);
445*042d53a7SEvalZero         if ((sum == 0) || (sum == (255 + 255 + 0x3f))) {
446*042d53a7SEvalZero             rc = 0;
447*042d53a7SEvalZero         }
448*042d53a7SEvalZero     } else if (addr_type == 0) {
449*042d53a7SEvalZero         /* non-resolvable. Cant be equal to public */
450*042d53a7SEvalZero         if (!memcmp(g_dev_addr, addr, BLE_DEV_ADDR_LEN)) {
451*042d53a7SEvalZero             rc = 0;
452*042d53a7SEvalZero         }
453*042d53a7SEvalZero     } else {
454*042d53a7SEvalZero         /* Invalid upper two bits */
455*042d53a7SEvalZero         rc = 0;
456*042d53a7SEvalZero     }
457*042d53a7SEvalZero 
458*042d53a7SEvalZero     return rc;
459*042d53a7SEvalZero }
460*042d53a7SEvalZero 
461*042d53a7SEvalZero /**
462*042d53a7SEvalZero  * Called from the HCI command parser when the set random address command
463*042d53a7SEvalZero  * is received.
464*042d53a7SEvalZero  *
465*042d53a7SEvalZero  * Context: Link Layer task (HCI command parser)
466*042d53a7SEvalZero  *
467*042d53a7SEvalZero  * @param addr Pointer to address
468*042d53a7SEvalZero  *
469*042d53a7SEvalZero  * @return int 0: success
470*042d53a7SEvalZero  */
471*042d53a7SEvalZero int
ble_ll_set_random_addr(uint8_t * addr,bool hci_adv_ext)472*042d53a7SEvalZero ble_ll_set_random_addr(uint8_t *addr, bool hci_adv_ext)
473*042d53a7SEvalZero {
474*042d53a7SEvalZero     /* If the Host issues this command when scanning or legacy advertising is
475*042d53a7SEvalZero      * enabled, the Controller shall return the error code Command Disallowed.
476*042d53a7SEvalZero      *
477*042d53a7SEvalZero      * Test specification extends this also to initiating.
478*042d53a7SEvalZero      */
479*042d53a7SEvalZero 
480*042d53a7SEvalZero     if (g_ble_ll_conn_create_sm || ble_ll_scan_enabled() ||
481*042d53a7SEvalZero                                 (!hci_adv_ext && ble_ll_adv_enabled())) {
482*042d53a7SEvalZero         return BLE_ERR_CMD_DISALLOWED;
483*042d53a7SEvalZero     }
484*042d53a7SEvalZero 
485*042d53a7SEvalZero     if (!ble_ll_is_valid_random_addr(addr)) {
486*042d53a7SEvalZero         return BLE_ERR_INV_HCI_CMD_PARMS;
487*042d53a7SEvalZero     }
488*042d53a7SEvalZero 
489*042d53a7SEvalZero     memcpy(g_random_addr, addr, BLE_DEV_ADDR_LEN);
490*042d53a7SEvalZero 
491*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
492*042d53a7SEvalZero     /* For instance 0 we need same address if legacy advertising might be
493*042d53a7SEvalZero      * used. If extended advertising is in use than this command doesn't
494*042d53a7SEvalZero      * affect instance 0.
495*042d53a7SEvalZero      */
496*042d53a7SEvalZero     if (!hci_adv_ext)
497*042d53a7SEvalZero         ble_ll_adv_set_random_addr(addr, 0);
498*042d53a7SEvalZero #endif
499*042d53a7SEvalZero 
500*042d53a7SEvalZero     return BLE_ERR_SUCCESS;
501*042d53a7SEvalZero }
502*042d53a7SEvalZero 
503*042d53a7SEvalZero /**
504*042d53a7SEvalZero  * Checks to see if an address is our device address (either public or
505*042d53a7SEvalZero  * random)
506*042d53a7SEvalZero  *
507*042d53a7SEvalZero  * @param addr
508*042d53a7SEvalZero  * @param addr_type
509*042d53a7SEvalZero  *
510*042d53a7SEvalZero  * @return int 0: not our device address. 1: is our device address
511*042d53a7SEvalZero  */
512*042d53a7SEvalZero int
ble_ll_is_our_devaddr(uint8_t * addr,int addr_type)513*042d53a7SEvalZero ble_ll_is_our_devaddr(uint8_t *addr, int addr_type)
514*042d53a7SEvalZero {
515*042d53a7SEvalZero     int rc;
516*042d53a7SEvalZero     uint8_t *our_addr;
517*042d53a7SEvalZero 
518*042d53a7SEvalZero     if (addr_type) {
519*042d53a7SEvalZero         our_addr = g_random_addr;
520*042d53a7SEvalZero     } else {
521*042d53a7SEvalZero         our_addr = g_dev_addr;
522*042d53a7SEvalZero     }
523*042d53a7SEvalZero 
524*042d53a7SEvalZero     rc = 0;
525*042d53a7SEvalZero     if (!memcmp(our_addr, addr, BLE_DEV_ADDR_LEN)) {
526*042d53a7SEvalZero         rc = 1;
527*042d53a7SEvalZero     }
528*042d53a7SEvalZero 
529*042d53a7SEvalZero     return rc;
530*042d53a7SEvalZero }
531*042d53a7SEvalZero 
532*042d53a7SEvalZero /**
533*042d53a7SEvalZero  * Get identity address
534*042d53a7SEvalZero  *
535*042d53a7SEvalZero  * @param addr_type Random (1). Public(0)
536*042d53a7SEvalZero  *
537*042d53a7SEvalZero  * @return pointer to identity address of given type.
538*042d53a7SEvalZero  */
539*042d53a7SEvalZero uint8_t*
ble_ll_get_our_devaddr(uint8_t addr_type)540*042d53a7SEvalZero ble_ll_get_our_devaddr(uint8_t addr_type)
541*042d53a7SEvalZero {
542*042d53a7SEvalZero     if (addr_type) {
543*042d53a7SEvalZero         return g_random_addr;
544*042d53a7SEvalZero     }
545*042d53a7SEvalZero 
546*042d53a7SEvalZero     return g_dev_addr;
547*042d53a7SEvalZero }
548*042d53a7SEvalZero 
549*042d53a7SEvalZero /**
550*042d53a7SEvalZero  * Wait for response timeout function
551*042d53a7SEvalZero  *
552*042d53a7SEvalZero  * Context: interrupt (ble scheduler)
553*042d53a7SEvalZero  *
554*042d53a7SEvalZero  * @param arg
555*042d53a7SEvalZero  */
556*042d53a7SEvalZero void
ble_ll_wfr_timer_exp(void * arg)557*042d53a7SEvalZero ble_ll_wfr_timer_exp(void *arg)
558*042d53a7SEvalZero {
559*042d53a7SEvalZero     int rx_start;
560*042d53a7SEvalZero     uint8_t lls;
561*042d53a7SEvalZero 
562*042d53a7SEvalZero     rx_start = ble_phy_rx_started();
563*042d53a7SEvalZero     lls = g_ble_ll_data.ll_state;
564*042d53a7SEvalZero 
565*042d53a7SEvalZero     ble_ll_trace_u32x3(BLE_LL_TRACE_ID_WFR_EXP, lls, ble_phy_xcvr_state_get(),
566*042d53a7SEvalZero                        (uint32_t)rx_start);
567*042d53a7SEvalZero 
568*042d53a7SEvalZero     /* If we have started a reception, there is nothing to do here */
569*042d53a7SEvalZero     if (!rx_start) {
570*042d53a7SEvalZero         switch (lls) {
571*042d53a7SEvalZero         case BLE_LL_STATE_ADV:
572*042d53a7SEvalZero             ble_ll_adv_wfr_timer_exp();
573*042d53a7SEvalZero             break;
574*042d53a7SEvalZero         case BLE_LL_STATE_CONNECTION:
575*042d53a7SEvalZero             ble_ll_conn_wfr_timer_exp();
576*042d53a7SEvalZero             break;
577*042d53a7SEvalZero         case BLE_LL_STATE_SCANNING:
578*042d53a7SEvalZero             ble_ll_scan_wfr_timer_exp();
579*042d53a7SEvalZero             break;
580*042d53a7SEvalZero         case BLE_LL_STATE_INITIATING:
581*042d53a7SEvalZero             ble_ll_conn_init_wfr_timer_exp();
582*042d53a7SEvalZero             break;
583*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
584*042d53a7SEvalZero         case BLE_LL_STATE_DTM:
585*042d53a7SEvalZero             ble_ll_dtm_wfr_timer_exp();
586*042d53a7SEvalZero             break;
587*042d53a7SEvalZero #endif
588*042d53a7SEvalZero         default:
589*042d53a7SEvalZero             break;
590*042d53a7SEvalZero         }
591*042d53a7SEvalZero     }
592*042d53a7SEvalZero }
593*042d53a7SEvalZero 
594*042d53a7SEvalZero /**
595*042d53a7SEvalZero  * Enable the wait for response timer.
596*042d53a7SEvalZero  *
597*042d53a7SEvalZero  * Context: Interrupt.
598*042d53a7SEvalZero  *
599*042d53a7SEvalZero  * @param cputime
600*042d53a7SEvalZero  * @param wfr_cb
601*042d53a7SEvalZero  * @param arg
602*042d53a7SEvalZero  */
603*042d53a7SEvalZero void
ble_ll_wfr_enable(uint32_t cputime)604*042d53a7SEvalZero ble_ll_wfr_enable(uint32_t cputime)
605*042d53a7SEvalZero {
606*042d53a7SEvalZero }
607*042d53a7SEvalZero 
608*042d53a7SEvalZero /**
609*042d53a7SEvalZero  * Disable the wait for response timer
610*042d53a7SEvalZero  */
611*042d53a7SEvalZero void
ble_ll_wfr_disable(void)612*042d53a7SEvalZero ble_ll_wfr_disable(void)
613*042d53a7SEvalZero {
614*042d53a7SEvalZero }
615*042d53a7SEvalZero 
616*042d53a7SEvalZero /**
617*042d53a7SEvalZero  * ll tx pkt in proc
618*042d53a7SEvalZero  *
619*042d53a7SEvalZero  * Process ACL data packet input from host
620*042d53a7SEvalZero  *
621*042d53a7SEvalZero  * Context: Link layer task
622*042d53a7SEvalZero  *
623*042d53a7SEvalZero  */
624*042d53a7SEvalZero static void
ble_ll_tx_pkt_in(void)625*042d53a7SEvalZero ble_ll_tx_pkt_in(void)
626*042d53a7SEvalZero {
627*042d53a7SEvalZero     uint16_t handle;
628*042d53a7SEvalZero     uint16_t length;
629*042d53a7SEvalZero     uint16_t pb;
630*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
631*042d53a7SEvalZero     struct os_mbuf *om;
632*042d53a7SEvalZero 
633*042d53a7SEvalZero     /* Drain all packets off the queue */
634*042d53a7SEvalZero     while (STAILQ_FIRST(&g_ble_ll_data.ll_tx_pkt_q)) {
635*042d53a7SEvalZero         /* Get mbuf pointer from packet header pointer */
636*042d53a7SEvalZero         pkthdr = STAILQ_FIRST(&g_ble_ll_data.ll_tx_pkt_q);
637*042d53a7SEvalZero         om = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
638*042d53a7SEvalZero 
639*042d53a7SEvalZero         /* Remove from queue */
640*042d53a7SEvalZero         STAILQ_REMOVE_HEAD(&g_ble_ll_data.ll_tx_pkt_q, omp_next);
641*042d53a7SEvalZero 
642*042d53a7SEvalZero         /* Strip HCI ACL header to get handle and length */
643*042d53a7SEvalZero         handle = get_le16(om->om_data);
644*042d53a7SEvalZero         length = get_le16(om->om_data + 2);
645*042d53a7SEvalZero         os_mbuf_adj(om, sizeof(struct hci_data_hdr));
646*042d53a7SEvalZero 
647*042d53a7SEvalZero         /* Do some basic error checking */
648*042d53a7SEvalZero         pb = handle & 0x3000;
649*042d53a7SEvalZero         if ((pkthdr->omp_len != length) || (pb > 0x1000) || (length == 0)) {
650*042d53a7SEvalZero             /* This is a bad ACL packet. Count a stat and free it */
651*042d53a7SEvalZero             STATS_INC(ble_ll_stats, bad_acl_hdr);
652*042d53a7SEvalZero             os_mbuf_free_chain(om);
653*042d53a7SEvalZero             continue;
654*042d53a7SEvalZero         }
655*042d53a7SEvalZero 
656*042d53a7SEvalZero         /* Hand to connection state machine */
657*042d53a7SEvalZero         ble_ll_conn_tx_pkt_in(om, handle, length);
658*042d53a7SEvalZero     }
659*042d53a7SEvalZero }
660*042d53a7SEvalZero 
661*042d53a7SEvalZero /**
662*042d53a7SEvalZero  * Count Link Layer statistics for received PDUs
663*042d53a7SEvalZero  *
664*042d53a7SEvalZero  * Context: Link layer task
665*042d53a7SEvalZero  *
666*042d53a7SEvalZero  * @param hdr
667*042d53a7SEvalZero  * @param len
668*042d53a7SEvalZero  */
669*042d53a7SEvalZero static void
ble_ll_count_rx_stats(struct ble_mbuf_hdr * hdr,uint16_t len,uint8_t pdu_type)670*042d53a7SEvalZero ble_ll_count_rx_stats(struct ble_mbuf_hdr *hdr, uint16_t len, uint8_t pdu_type)
671*042d53a7SEvalZero {
672*042d53a7SEvalZero     uint8_t crcok;
673*042d53a7SEvalZero     bool connection_data;
674*042d53a7SEvalZero 
675*042d53a7SEvalZero     crcok = BLE_MBUF_HDR_CRC_OK(hdr);
676*042d53a7SEvalZero     connection_data = (BLE_MBUF_HDR_RX_STATE(hdr) == BLE_LL_STATE_CONNECTION);
677*042d53a7SEvalZero 
678*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
679*042d53a7SEvalZero     /* Reuse connection stats for DTM */
680*042d53a7SEvalZero     connection_data = (BLE_MBUF_HDR_RX_STATE(hdr) == BLE_LL_STATE_DTM);
681*042d53a7SEvalZero #endif
682*042d53a7SEvalZero 
683*042d53a7SEvalZero     if (crcok) {
684*042d53a7SEvalZero         if (connection_data) {
685*042d53a7SEvalZero             STATS_INC(ble_ll_stats, rx_data_pdu_crc_ok);
686*042d53a7SEvalZero             STATS_INCN(ble_ll_stats, rx_data_bytes_crc_ok, len);
687*042d53a7SEvalZero         } else {
688*042d53a7SEvalZero             STATS_INC(ble_ll_stats, rx_adv_pdu_crc_ok);
689*042d53a7SEvalZero             STATS_INCN(ble_ll_stats, rx_adv_bytes_crc_ok, len);
690*042d53a7SEvalZero             ble_ll_count_rx_adv_pdus(pdu_type);
691*042d53a7SEvalZero         }
692*042d53a7SEvalZero     } else {
693*042d53a7SEvalZero         if (connection_data) {
694*042d53a7SEvalZero             STATS_INC(ble_ll_stats, rx_data_pdu_crc_err);
695*042d53a7SEvalZero             STATS_INCN(ble_ll_stats, rx_data_bytes_crc_err, len);
696*042d53a7SEvalZero         } else {
697*042d53a7SEvalZero             STATS_INC(ble_ll_stats, rx_adv_pdu_crc_err);
698*042d53a7SEvalZero             STATS_INCN(ble_ll_stats, rx_adv_bytes_crc_err, len);
699*042d53a7SEvalZero         }
700*042d53a7SEvalZero     }
701*042d53a7SEvalZero }
702*042d53a7SEvalZero 
703*042d53a7SEvalZero /**
704*042d53a7SEvalZero  * ll rx pkt in
705*042d53a7SEvalZero  *
706*042d53a7SEvalZero  * Process received packet from PHY.
707*042d53a7SEvalZero  *
708*042d53a7SEvalZero  * Context: Link layer task
709*042d53a7SEvalZero  *
710*042d53a7SEvalZero  */
711*042d53a7SEvalZero static void
ble_ll_rx_pkt_in(void)712*042d53a7SEvalZero ble_ll_rx_pkt_in(void)
713*042d53a7SEvalZero {
714*042d53a7SEvalZero     os_sr_t sr;
715*042d53a7SEvalZero     uint8_t pdu_type;
716*042d53a7SEvalZero     uint8_t *rxbuf;
717*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
718*042d53a7SEvalZero     struct ble_mbuf_hdr *ble_hdr;
719*042d53a7SEvalZero     struct os_mbuf *m;
720*042d53a7SEvalZero 
721*042d53a7SEvalZero     /* Drain all packets off the queue */
722*042d53a7SEvalZero     while (STAILQ_FIRST(&g_ble_ll_data.ll_rx_pkt_q)) {
723*042d53a7SEvalZero         /* Get mbuf pointer from packet header pointer */
724*042d53a7SEvalZero         pkthdr = STAILQ_FIRST(&g_ble_ll_data.ll_rx_pkt_q);
725*042d53a7SEvalZero         m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
726*042d53a7SEvalZero 
727*042d53a7SEvalZero         /* Remove from queue */
728*042d53a7SEvalZero         OS_ENTER_CRITICAL(sr);
729*042d53a7SEvalZero         STAILQ_REMOVE_HEAD(&g_ble_ll_data.ll_rx_pkt_q, omp_next);
730*042d53a7SEvalZero         OS_EXIT_CRITICAL(sr);
731*042d53a7SEvalZero 
732*042d53a7SEvalZero         /* Note: pdu type wont get used unless this is an advertising pdu */
733*042d53a7SEvalZero         ble_hdr = BLE_MBUF_HDR_PTR(m);
734*042d53a7SEvalZero         rxbuf = m->om_data;
735*042d53a7SEvalZero         pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
736*042d53a7SEvalZero         ble_ll_count_rx_stats(ble_hdr, pkthdr->omp_len, pdu_type);
737*042d53a7SEvalZero 
738*042d53a7SEvalZero         /* Process the data or advertising pdu */
739*042d53a7SEvalZero         /* Process the PDU */
740*042d53a7SEvalZero         switch (BLE_MBUF_HDR_RX_STATE(ble_hdr)) {
741*042d53a7SEvalZero         case BLE_LL_STATE_CONNECTION:
742*042d53a7SEvalZero             ble_ll_conn_rx_data_pdu(m, ble_hdr);
743*042d53a7SEvalZero             /* m is going to be free by function above */
744*042d53a7SEvalZero             m = NULL;
745*042d53a7SEvalZero             break;
746*042d53a7SEvalZero         case BLE_LL_STATE_ADV:
747*042d53a7SEvalZero             ble_ll_adv_rx_pkt_in(pdu_type, rxbuf, ble_hdr);
748*042d53a7SEvalZero             break;
749*042d53a7SEvalZero         case BLE_LL_STATE_SCANNING:
750*042d53a7SEvalZero             ble_ll_scan_rx_pkt_in(pdu_type, m, ble_hdr);
751*042d53a7SEvalZero             break;
752*042d53a7SEvalZero         case BLE_LL_STATE_INITIATING:
753*042d53a7SEvalZero             ble_ll_init_rx_pkt_in(pdu_type, rxbuf, ble_hdr);
754*042d53a7SEvalZero             break;
755*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
756*042d53a7SEvalZero         case BLE_LL_STATE_DTM:
757*042d53a7SEvalZero             ble_ll_dtm_rx_pkt_in(m, ble_hdr);
758*042d53a7SEvalZero             break;
759*042d53a7SEvalZero #endif
760*042d53a7SEvalZero         default:
761*042d53a7SEvalZero             /* Any other state should never occur */
762*042d53a7SEvalZero             STATS_INC(ble_ll_stats, bad_ll_state);
763*042d53a7SEvalZero             break;
764*042d53a7SEvalZero         }
765*042d53a7SEvalZero         if (m) {
766*042d53a7SEvalZero             /* Free the packet buffer */
767*042d53a7SEvalZero             os_mbuf_free_chain(m);
768*042d53a7SEvalZero         }
769*042d53a7SEvalZero     }
770*042d53a7SEvalZero }
771*042d53a7SEvalZero 
772*042d53a7SEvalZero /**
773*042d53a7SEvalZero  * Called to put a packet on the Link Layer receive packet queue.
774*042d53a7SEvalZero  *
775*042d53a7SEvalZero  * @param rxpdu Pointer to received PDU
776*042d53a7SEvalZero  */
777*042d53a7SEvalZero void
ble_ll_rx_pdu_in(struct os_mbuf * rxpdu)778*042d53a7SEvalZero ble_ll_rx_pdu_in(struct os_mbuf *rxpdu)
779*042d53a7SEvalZero {
780*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
781*042d53a7SEvalZero 
782*042d53a7SEvalZero     pkthdr = OS_MBUF_PKTHDR(rxpdu);
783*042d53a7SEvalZero     STAILQ_INSERT_TAIL(&g_ble_ll_data.ll_rx_pkt_q, pkthdr, omp_next);
784*042d53a7SEvalZero     ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_rx_pkt_ev);
785*042d53a7SEvalZero }
786*042d53a7SEvalZero 
787*042d53a7SEvalZero /**
788*042d53a7SEvalZero  * Called to put a packet on the Link Layer transmit packet queue.
789*042d53a7SEvalZero  *
790*042d53a7SEvalZero  * @param txpdu Pointer to transmit packet
791*042d53a7SEvalZero  */
792*042d53a7SEvalZero void
ble_ll_acl_data_in(struct os_mbuf * txpkt)793*042d53a7SEvalZero ble_ll_acl_data_in(struct os_mbuf *txpkt)
794*042d53a7SEvalZero {
795*042d53a7SEvalZero     os_sr_t sr;
796*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
797*042d53a7SEvalZero 
798*042d53a7SEvalZero     pkthdr = OS_MBUF_PKTHDR(txpkt);
799*042d53a7SEvalZero     OS_ENTER_CRITICAL(sr);
800*042d53a7SEvalZero     STAILQ_INSERT_TAIL(&g_ble_ll_data.ll_tx_pkt_q, pkthdr, omp_next);
801*042d53a7SEvalZero     OS_EXIT_CRITICAL(sr);
802*042d53a7SEvalZero     ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_tx_pkt_ev);
803*042d53a7SEvalZero }
804*042d53a7SEvalZero 
805*042d53a7SEvalZero /**
806*042d53a7SEvalZero  * Called to post event to Link Layer when a data buffer overflow has
807*042d53a7SEvalZero  * occurred.
808*042d53a7SEvalZero  *
809*042d53a7SEvalZero  * Context: Interrupt
810*042d53a7SEvalZero  *
811*042d53a7SEvalZero  */
812*042d53a7SEvalZero void
ble_ll_data_buffer_overflow(void)813*042d53a7SEvalZero ble_ll_data_buffer_overflow(void)
814*042d53a7SEvalZero {
815*042d53a7SEvalZero     ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_dbuf_overflow_ev);
816*042d53a7SEvalZero }
817*042d53a7SEvalZero 
818*042d53a7SEvalZero /**
819*042d53a7SEvalZero  * Called when a HW error occurs.
820*042d53a7SEvalZero  *
821*042d53a7SEvalZero  * Context: Interrupt
822*042d53a7SEvalZero  */
823*042d53a7SEvalZero void
ble_ll_hw_error(void)824*042d53a7SEvalZero ble_ll_hw_error(void)
825*042d53a7SEvalZero {
826*042d53a7SEvalZero     ble_npl_callout_reset(&g_ble_ll_data.ll_hw_err_timer, 0);
827*042d53a7SEvalZero }
828*042d53a7SEvalZero 
829*042d53a7SEvalZero /**
830*042d53a7SEvalZero  * Called when the HW error timer expires.
831*042d53a7SEvalZero  *
832*042d53a7SEvalZero  * @param arg
833*042d53a7SEvalZero  */
834*042d53a7SEvalZero static void
ble_ll_hw_err_timer_cb(struct ble_npl_event * ev)835*042d53a7SEvalZero ble_ll_hw_err_timer_cb(struct ble_npl_event *ev)
836*042d53a7SEvalZero {
837*042d53a7SEvalZero     if (ble_ll_hci_ev_hw_err(BLE_HW_ERR_HCI_SYNC_LOSS)) {
838*042d53a7SEvalZero         /*
839*042d53a7SEvalZero          * Restart callout if failed to allocate event. Try to allocate an
840*042d53a7SEvalZero          * event every 50 milliseconds (or each OS tick if a tick is longer
841*042d53a7SEvalZero          * than 100 msecs).
842*042d53a7SEvalZero          */
843*042d53a7SEvalZero         ble_npl_callout_reset(&g_ble_ll_data.ll_hw_err_timer,
844*042d53a7SEvalZero                          ble_npl_time_ms_to_ticks32(50));
845*042d53a7SEvalZero     }
846*042d53a7SEvalZero }
847*042d53a7SEvalZero 
848*042d53a7SEvalZero /**
849*042d53a7SEvalZero  * Called upon start of received PDU
850*042d53a7SEvalZero  *
851*042d53a7SEvalZero  * Context: Interrupt
852*042d53a7SEvalZero  *
853*042d53a7SEvalZero  * @param rxpdu
854*042d53a7SEvalZero  *        chan
855*042d53a7SEvalZero  *
856*042d53a7SEvalZero  * @return int
857*042d53a7SEvalZero  *   < 0: A frame we dont want to receive.
858*042d53a7SEvalZero  *   = 0: Continue to receive frame. Dont go from rx to tx
859*042d53a7SEvalZero  *   > 0: Continue to receive frame and go from rx to tx when done
860*042d53a7SEvalZero  */
861*042d53a7SEvalZero int
ble_ll_rx_start(uint8_t * rxbuf,uint8_t chan,struct ble_mbuf_hdr * rxhdr)862*042d53a7SEvalZero ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr)
863*042d53a7SEvalZero {
864*042d53a7SEvalZero     int rc;
865*042d53a7SEvalZero     uint8_t pdu_type;
866*042d53a7SEvalZero 
867*042d53a7SEvalZero     /* Advertising channel PDU */
868*042d53a7SEvalZero     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
869*042d53a7SEvalZero 
870*042d53a7SEvalZero     ble_ll_trace_u32x2(BLE_LL_TRACE_ID_RX_START, g_ble_ll_data.ll_state,
871*042d53a7SEvalZero                        pdu_type);
872*042d53a7SEvalZero 
873*042d53a7SEvalZero     switch (g_ble_ll_data.ll_state) {
874*042d53a7SEvalZero     case BLE_LL_STATE_CONNECTION:
875*042d53a7SEvalZero         rc = ble_ll_conn_rx_isr_start(rxhdr, ble_phy_access_addr_get());
876*042d53a7SEvalZero         break;
877*042d53a7SEvalZero     case BLE_LL_STATE_ADV:
878*042d53a7SEvalZero         rc = ble_ll_adv_rx_isr_start(pdu_type);
879*042d53a7SEvalZero         break;
880*042d53a7SEvalZero     case BLE_LL_STATE_INITIATING:
881*042d53a7SEvalZero         rc = ble_ll_init_rx_isr_start(pdu_type, rxhdr);
882*042d53a7SEvalZero         break;
883*042d53a7SEvalZero     case BLE_LL_STATE_SCANNING:
884*042d53a7SEvalZero         rc = ble_ll_scan_rx_isr_start(pdu_type, &rxhdr->rxinfo.flags);
885*042d53a7SEvalZero         break;
886*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
887*042d53a7SEvalZero     case BLE_LL_STATE_DTM:
888*042d53a7SEvalZero         rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get());
889*042d53a7SEvalZero         break;
890*042d53a7SEvalZero #endif
891*042d53a7SEvalZero     default:
892*042d53a7SEvalZero         /* Should not be in this state! */
893*042d53a7SEvalZero         rc = -1;
894*042d53a7SEvalZero         STATS_INC(ble_ll_stats, bad_ll_state);
895*042d53a7SEvalZero         break;
896*042d53a7SEvalZero     }
897*042d53a7SEvalZero 
898*042d53a7SEvalZero     return rc;
899*042d53a7SEvalZero }
900*042d53a7SEvalZero 
901*042d53a7SEvalZero /**
902*042d53a7SEvalZero  * Called by the PHY when a receive packet has ended.
903*042d53a7SEvalZero  *
904*042d53a7SEvalZero  * NOTE: Called from interrupt context!
905*042d53a7SEvalZero  *
906*042d53a7SEvalZero  * @param rxbuf Pointer to received PDU data
907*042d53a7SEvalZero  *        rxhdr Pointer to BLE header of received mbuf
908*042d53a7SEvalZero  *
909*042d53a7SEvalZero  * @return int
910*042d53a7SEvalZero  *       < 0: Disable the phy after reception.
911*042d53a7SEvalZero  *      == 0: Success. Do not disable the PHY.
912*042d53a7SEvalZero  *       > 0: Do not disable PHY as that has already been done.
913*042d53a7SEvalZero  */
914*042d53a7SEvalZero int
ble_ll_rx_end(uint8_t * rxbuf,struct ble_mbuf_hdr * rxhdr)915*042d53a7SEvalZero ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
916*042d53a7SEvalZero {
917*042d53a7SEvalZero     int rc;
918*042d53a7SEvalZero     int badpkt;
919*042d53a7SEvalZero     uint8_t pdu_type;
920*042d53a7SEvalZero     uint8_t len;
921*042d53a7SEvalZero     uint8_t crcok;
922*042d53a7SEvalZero     struct os_mbuf *rxpdu;
923*042d53a7SEvalZero 
924*042d53a7SEvalZero     /* Get CRC status from BLE header */
925*042d53a7SEvalZero     crcok = BLE_MBUF_HDR_CRC_OK(rxhdr);
926*042d53a7SEvalZero 
927*042d53a7SEvalZero     /* Get advertising PDU type and length */
928*042d53a7SEvalZero     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
929*042d53a7SEvalZero     len = rxbuf[1];
930*042d53a7SEvalZero 
931*042d53a7SEvalZero     ble_ll_trace_u32x3(BLE_LL_TRACE_ID_RX_END, pdu_type, len,
932*042d53a7SEvalZero                        rxhdr->rxinfo.flags);
933*042d53a7SEvalZero 
934*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
935*042d53a7SEvalZero     if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_DTM) {
936*042d53a7SEvalZero         rc = ble_ll_dtm_rx_isr_end(rxbuf, rxhdr);
937*042d53a7SEvalZero         return rc;
938*042d53a7SEvalZero     }
939*042d53a7SEvalZero #endif
940*042d53a7SEvalZero 
941*042d53a7SEvalZero     if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_CONNECTION) {
942*042d53a7SEvalZero         rc = ble_ll_conn_rx_isr_end(rxbuf, rxhdr);
943*042d53a7SEvalZero         return rc;
944*042d53a7SEvalZero     }
945*042d53a7SEvalZero 
946*042d53a7SEvalZero     /* If the CRC checks, make sure lengths check! */
947*042d53a7SEvalZero     badpkt = 0;
948*042d53a7SEvalZero     if (crcok) {
949*042d53a7SEvalZero         switch (pdu_type) {
950*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_SCAN_REQ:
951*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
952*042d53a7SEvalZero             if (len != BLE_SCAN_REQ_LEN) {
953*042d53a7SEvalZero                 badpkt = 1;
954*042d53a7SEvalZero             }
955*042d53a7SEvalZero             break;
956*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_SCAN_RSP:
957*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_ADV_IND:
958*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_ADV_SCAN_IND:
959*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND:
960*042d53a7SEvalZero             if ((len < BLE_DEV_ADDR_LEN) || (len > BLE_ADV_SCAN_IND_MAX_LEN)) {
961*042d53a7SEvalZero                 badpkt = 1;
962*042d53a7SEvalZero             }
963*042d53a7SEvalZero             break;
964*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP:
965*042d53a7SEvalZero             break;
966*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_ADV_EXT_IND:
967*042d53a7SEvalZero             break;
968*042d53a7SEvalZero         case BLE_ADV_PDU_TYPE_CONNECT_REQ:
969*042d53a7SEvalZero             if (len != BLE_CONNECT_REQ_LEN) {
970*042d53a7SEvalZero                 badpkt = 1;
971*042d53a7SEvalZero             }
972*042d53a7SEvalZero             break;
973*042d53a7SEvalZero         default:
974*042d53a7SEvalZero             badpkt = 1;
975*042d53a7SEvalZero             break;
976*042d53a7SEvalZero         }
977*042d53a7SEvalZero 
978*042d53a7SEvalZero         /* If this is a malformed packet, just kill it here */
979*042d53a7SEvalZero         if (badpkt) {
980*042d53a7SEvalZero             STATS_INC(ble_ll_stats, rx_adv_malformed_pkts);
981*042d53a7SEvalZero         }
982*042d53a7SEvalZero     }
983*042d53a7SEvalZero 
984*042d53a7SEvalZero     /* Hand packet to the appropriate state machine (if crc ok) */
985*042d53a7SEvalZero     rxpdu = NULL;
986*042d53a7SEvalZero     switch (BLE_MBUF_HDR_RX_STATE(rxhdr)) {
987*042d53a7SEvalZero     case BLE_LL_STATE_ADV:
988*042d53a7SEvalZero         if (!badpkt) {
989*042d53a7SEvalZero             rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN);
990*042d53a7SEvalZero             if (rxpdu) {
991*042d53a7SEvalZero                 ble_phy_rxpdu_copy(rxbuf, rxpdu);
992*042d53a7SEvalZero             }
993*042d53a7SEvalZero         }
994*042d53a7SEvalZero         rc = ble_ll_adv_rx_isr_end(pdu_type, rxpdu, crcok);
995*042d53a7SEvalZero         break;
996*042d53a7SEvalZero     case BLE_LL_STATE_SCANNING:
997*042d53a7SEvalZero         if (!badpkt) {
998*042d53a7SEvalZero             rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN);
999*042d53a7SEvalZero             if (rxpdu) {
1000*042d53a7SEvalZero                 ble_phy_rxpdu_copy(rxbuf, rxpdu);
1001*042d53a7SEvalZero             }
1002*042d53a7SEvalZero         }
1003*042d53a7SEvalZero         rc = ble_ll_scan_rx_isr_end(rxpdu, crcok);
1004*042d53a7SEvalZero         break;
1005*042d53a7SEvalZero     case BLE_LL_STATE_INITIATING:
1006*042d53a7SEvalZero         rc = ble_ll_init_rx_isr_end(rxbuf, crcok, rxhdr);
1007*042d53a7SEvalZero         break;
1008*042d53a7SEvalZero     default:
1009*042d53a7SEvalZero         rc = -1;
1010*042d53a7SEvalZero         STATS_INC(ble_ll_stats, bad_ll_state);
1011*042d53a7SEvalZero         break;
1012*042d53a7SEvalZero     }
1013*042d53a7SEvalZero 
1014*042d53a7SEvalZero     /* Hand packet up to higher layer (regardless of CRC failure) */
1015*042d53a7SEvalZero     if (rxpdu) {
1016*042d53a7SEvalZero         ble_ll_rx_pdu_in(rxpdu);
1017*042d53a7SEvalZero     }
1018*042d53a7SEvalZero 
1019*042d53a7SEvalZero     return rc;
1020*042d53a7SEvalZero }
1021*042d53a7SEvalZero 
1022*042d53a7SEvalZero uint8_t
ble_ll_tx_mbuf_pducb(uint8_t * dptr,void * pducb_arg,uint8_t * hdr_byte)1023*042d53a7SEvalZero ble_ll_tx_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
1024*042d53a7SEvalZero {
1025*042d53a7SEvalZero     struct os_mbuf *txpdu;
1026*042d53a7SEvalZero     struct ble_mbuf_hdr *ble_hdr;
1027*042d53a7SEvalZero 
1028*042d53a7SEvalZero     txpdu = pducb_arg;
1029*042d53a7SEvalZero     BLE_LL_ASSERT(txpdu);
1030*042d53a7SEvalZero     ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
1031*042d53a7SEvalZero 
1032*042d53a7SEvalZero     os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, ble_hdr->txinfo.pyld_len,
1033*042d53a7SEvalZero                      dptr);
1034*042d53a7SEvalZero 
1035*042d53a7SEvalZero     *hdr_byte = ble_hdr->txinfo.hdr_byte;
1036*042d53a7SEvalZero 
1037*042d53a7SEvalZero     return ble_hdr->txinfo.pyld_len;
1038*042d53a7SEvalZero }
1039*042d53a7SEvalZero 
1040*042d53a7SEvalZero uint8_t
ble_ll_tx_flat_mbuf_pducb(uint8_t * dptr,void * pducb_arg,uint8_t * hdr_byte)1041*042d53a7SEvalZero ble_ll_tx_flat_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
1042*042d53a7SEvalZero {
1043*042d53a7SEvalZero     struct os_mbuf *txpdu;
1044*042d53a7SEvalZero     struct ble_mbuf_hdr *ble_hdr;
1045*042d53a7SEvalZero 
1046*042d53a7SEvalZero     txpdu = pducb_arg;
1047*042d53a7SEvalZero     BLE_LL_ASSERT(txpdu);
1048*042d53a7SEvalZero     ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
1049*042d53a7SEvalZero 
1050*042d53a7SEvalZero     memcpy(dptr, txpdu->om_data, ble_hdr->txinfo.pyld_len);
1051*042d53a7SEvalZero 
1052*042d53a7SEvalZero     *hdr_byte = ble_hdr->txinfo.hdr_byte;
1053*042d53a7SEvalZero 
1054*042d53a7SEvalZero     return ble_hdr->txinfo.pyld_len;
1055*042d53a7SEvalZero }
1056*042d53a7SEvalZero 
1057*042d53a7SEvalZero static void
ble_ll_event_rx_pkt(struct ble_npl_event * ev)1058*042d53a7SEvalZero ble_ll_event_rx_pkt(struct ble_npl_event *ev)
1059*042d53a7SEvalZero {
1060*042d53a7SEvalZero     ble_ll_rx_pkt_in();
1061*042d53a7SEvalZero }
1062*042d53a7SEvalZero 
1063*042d53a7SEvalZero static void
ble_ll_event_tx_pkt(struct ble_npl_event * ev)1064*042d53a7SEvalZero ble_ll_event_tx_pkt(struct ble_npl_event *ev)
1065*042d53a7SEvalZero {
1066*042d53a7SEvalZero     ble_ll_tx_pkt_in();
1067*042d53a7SEvalZero }
1068*042d53a7SEvalZero 
1069*042d53a7SEvalZero static void
ble_ll_event_dbuf_overflow(struct ble_npl_event * ev)1070*042d53a7SEvalZero ble_ll_event_dbuf_overflow(struct ble_npl_event *ev)
1071*042d53a7SEvalZero {
1072*042d53a7SEvalZero     ble_ll_hci_ev_databuf_overflow();
1073*042d53a7SEvalZero }
1074*042d53a7SEvalZero 
1075*042d53a7SEvalZero static void
ble_ll_event_comp_pkts(struct ble_npl_event * ev)1076*042d53a7SEvalZero ble_ll_event_comp_pkts(struct ble_npl_event *ev)
1077*042d53a7SEvalZero {
1078*042d53a7SEvalZero     ble_ll_conn_num_comp_pkts_event_send(NULL);
1079*042d53a7SEvalZero }
1080*042d53a7SEvalZero 
1081*042d53a7SEvalZero /**
1082*042d53a7SEvalZero  * Link Layer task.
1083*042d53a7SEvalZero  *
1084*042d53a7SEvalZero  * This is the task that runs the Link Layer.
1085*042d53a7SEvalZero  *
1086*042d53a7SEvalZero  * @param arg
1087*042d53a7SEvalZero  */
1088*042d53a7SEvalZero void
ble_ll_task(void * arg)1089*042d53a7SEvalZero ble_ll_task(void *arg)
1090*042d53a7SEvalZero {
1091*042d53a7SEvalZero     struct ble_npl_event *ev;
1092*042d53a7SEvalZero 
1093*042d53a7SEvalZero     /*
1094*042d53a7SEvalZero      * XXX RIOT ties event queue to a thread which initialized it so we need to
1095*042d53a7SEvalZero      * create event queue in LL task, not in general init function. This can
1096*042d53a7SEvalZero      * lead to some races between host and LL so for now let us have it as a
1097*042d53a7SEvalZero      * hack for RIOT where races can be avoided by proper initialization inside
1098*042d53a7SEvalZero      * package.
1099*042d53a7SEvalZero      */
1100*042d53a7SEvalZero #ifdef RIOT_VERSION
1101*042d53a7SEvalZero     ble_npl_eventq_init(&g_ble_ll_data.ll_evq);
1102*042d53a7SEvalZero #endif
1103*042d53a7SEvalZero 
1104*042d53a7SEvalZero     /* Init ble phy */
1105*042d53a7SEvalZero     ble_phy_init();
1106*042d53a7SEvalZero 
1107*042d53a7SEvalZero     /* Set output power to 1mW (0 dBm) */
1108*042d53a7SEvalZero     ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
1109*042d53a7SEvalZero 
1110*042d53a7SEvalZero     /* Tell the host that we are ready to receive packets */
1111*042d53a7SEvalZero     ble_ll_hci_send_noop();
1112*042d53a7SEvalZero 
1113*042d53a7SEvalZero     ble_ll_rand_start();
1114*042d53a7SEvalZero 
1115*042d53a7SEvalZero     while (1) {
1116*042d53a7SEvalZero         ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER);
1117*042d53a7SEvalZero         assert(ev);
1118*042d53a7SEvalZero         ble_npl_event_run(ev);
1119*042d53a7SEvalZero     }
1120*042d53a7SEvalZero }
1121*042d53a7SEvalZero 
1122*042d53a7SEvalZero /**
1123*042d53a7SEvalZero  * ble ll state set
1124*042d53a7SEvalZero  *
1125*042d53a7SEvalZero  * Called to set the current link layer state.
1126*042d53a7SEvalZero  *
1127*042d53a7SEvalZero  * Context: Interrupt and Link Layer task
1128*042d53a7SEvalZero  *
1129*042d53a7SEvalZero  * @param ll_state
1130*042d53a7SEvalZero  */
1131*042d53a7SEvalZero void
ble_ll_state_set(uint8_t ll_state)1132*042d53a7SEvalZero ble_ll_state_set(uint8_t ll_state)
1133*042d53a7SEvalZero {
1134*042d53a7SEvalZero     g_ble_ll_data.ll_state = ll_state;
1135*042d53a7SEvalZero }
1136*042d53a7SEvalZero 
1137*042d53a7SEvalZero /**
1138*042d53a7SEvalZero  * ble ll state get
1139*042d53a7SEvalZero  *
1140*042d53a7SEvalZero  * Called to get the current link layer state.
1141*042d53a7SEvalZero  *
1142*042d53a7SEvalZero  * Context: Link Layer task (can be called from interrupt context though).
1143*042d53a7SEvalZero  *
1144*042d53a7SEvalZero  * @return ll_state
1145*042d53a7SEvalZero  */
1146*042d53a7SEvalZero uint8_t
ble_ll_state_get(void)1147*042d53a7SEvalZero ble_ll_state_get(void)
1148*042d53a7SEvalZero {
1149*042d53a7SEvalZero     return g_ble_ll_data.ll_state;
1150*042d53a7SEvalZero }
1151*042d53a7SEvalZero 
1152*042d53a7SEvalZero /**
1153*042d53a7SEvalZero  * ble ll event send
1154*042d53a7SEvalZero  *
1155*042d53a7SEvalZero  * Send an event to the Link Layer task
1156*042d53a7SEvalZero  *
1157*042d53a7SEvalZero  * @param ev Event to add to the Link Layer event queue.
1158*042d53a7SEvalZero  */
1159*042d53a7SEvalZero void
ble_ll_event_send(struct ble_npl_event * ev)1160*042d53a7SEvalZero ble_ll_event_send(struct ble_npl_event *ev)
1161*042d53a7SEvalZero {
1162*042d53a7SEvalZero     ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev);
1163*042d53a7SEvalZero }
1164*042d53a7SEvalZero 
1165*042d53a7SEvalZero /**
1166*042d53a7SEvalZero  * Returns the features supported by the link layer
1167*042d53a7SEvalZero  *
1168*042d53a7SEvalZero  * @return uint8_t bitmask of supported features.
1169*042d53a7SEvalZero  */
1170*042d53a7SEvalZero uint64_t
ble_ll_read_supp_states(void)1171*042d53a7SEvalZero ble_ll_read_supp_states(void)
1172*042d53a7SEvalZero {
1173*042d53a7SEvalZero     return BLE_LL_SUPPORTED_STATES;
1174*042d53a7SEvalZero }
1175*042d53a7SEvalZero 
1176*042d53a7SEvalZero /**
1177*042d53a7SEvalZero  * Returns the features supported by the link layer
1178*042d53a7SEvalZero  *
1179*042d53a7SEvalZero  * @return uint32_t bitmask of supported features.
1180*042d53a7SEvalZero  */
1181*042d53a7SEvalZero uint32_t
ble_ll_read_supp_features(void)1182*042d53a7SEvalZero ble_ll_read_supp_features(void)
1183*042d53a7SEvalZero {
1184*042d53a7SEvalZero     return g_ble_ll_data.ll_supp_features;
1185*042d53a7SEvalZero }
1186*042d53a7SEvalZero 
1187*042d53a7SEvalZero /**
1188*042d53a7SEvalZero  * Flush a link layer packet queue.
1189*042d53a7SEvalZero  *
1190*042d53a7SEvalZero  * @param pktq
1191*042d53a7SEvalZero  */
1192*042d53a7SEvalZero static void
ble_ll_flush_pkt_queue(struct ble_ll_pkt_q * pktq)1193*042d53a7SEvalZero ble_ll_flush_pkt_queue(struct ble_ll_pkt_q *pktq)
1194*042d53a7SEvalZero {
1195*042d53a7SEvalZero     struct os_mbuf_pkthdr *pkthdr;
1196*042d53a7SEvalZero     struct os_mbuf *om;
1197*042d53a7SEvalZero 
1198*042d53a7SEvalZero     /* FLush all packets from Link layer queues */
1199*042d53a7SEvalZero     while (STAILQ_FIRST(pktq)) {
1200*042d53a7SEvalZero         /* Get mbuf pointer from packet header pointer */
1201*042d53a7SEvalZero         pkthdr = STAILQ_FIRST(pktq);
1202*042d53a7SEvalZero         om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
1203*042d53a7SEvalZero 
1204*042d53a7SEvalZero         /* Remove from queue and free the mbuf */
1205*042d53a7SEvalZero         STAILQ_REMOVE_HEAD(pktq, omp_next);
1206*042d53a7SEvalZero         os_mbuf_free_chain(om);
1207*042d53a7SEvalZero     }
1208*042d53a7SEvalZero }
1209*042d53a7SEvalZero 
1210*042d53a7SEvalZero /**
1211*042d53a7SEvalZero  * Called to initialize a mbuf used by the controller
1212*042d53a7SEvalZero  *
1213*042d53a7SEvalZero  * NOTE: this is only used when the mbuf is created by the controller;
1214*042d53a7SEvalZero  * it should not be used for data packets (ACL data packets) that come from
1215*042d53a7SEvalZero  * the host. This routine assumes that the entire pdu length can fit in
1216*042d53a7SEvalZero  * one mbuf contiguously.
1217*042d53a7SEvalZero  *
1218*042d53a7SEvalZero  * @param m
1219*042d53a7SEvalZero  * @param pdulen
1220*042d53a7SEvalZero  * @param hdr
1221*042d53a7SEvalZero  */
1222*042d53a7SEvalZero void
ble_ll_mbuf_init(struct os_mbuf * m,uint8_t pdulen,uint8_t hdr)1223*042d53a7SEvalZero ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr)
1224*042d53a7SEvalZero {
1225*042d53a7SEvalZero     struct ble_mbuf_hdr *ble_hdr;
1226*042d53a7SEvalZero 
1227*042d53a7SEvalZero     /* Set mbuf length and packet length */
1228*042d53a7SEvalZero     m->om_len = pdulen;
1229*042d53a7SEvalZero     OS_MBUF_PKTHDR(m)->omp_len = pdulen;
1230*042d53a7SEvalZero 
1231*042d53a7SEvalZero     /* Set BLE transmit header */
1232*042d53a7SEvalZero     ble_hdr = BLE_MBUF_HDR_PTR(m);
1233*042d53a7SEvalZero     ble_hdr->txinfo.flags = 0;
1234*042d53a7SEvalZero     ble_hdr->txinfo.offset = 0;
1235*042d53a7SEvalZero     ble_hdr->txinfo.pyld_len = pdulen;
1236*042d53a7SEvalZero     ble_hdr->txinfo.hdr_byte = hdr;
1237*042d53a7SEvalZero }
1238*042d53a7SEvalZero 
1239*042d53a7SEvalZero /**
1240*042d53a7SEvalZero  * Called to reset the controller. This performs a "software reset" of the link
1241*042d53a7SEvalZero  * layer; it does not perform a HW reset of the controller nor does it reset
1242*042d53a7SEvalZero  * the HCI interface.
1243*042d53a7SEvalZero  *
1244*042d53a7SEvalZero  * Context: Link Layer task (HCI command)
1245*042d53a7SEvalZero  *
1246*042d53a7SEvalZero  * @return int The ble error code to place in the command complete event that
1247*042d53a7SEvalZero  * is returned when this command is issued.
1248*042d53a7SEvalZero  */
1249*042d53a7SEvalZero int
ble_ll_reset(void)1250*042d53a7SEvalZero ble_ll_reset(void)
1251*042d53a7SEvalZero {
1252*042d53a7SEvalZero     int rc;
1253*042d53a7SEvalZero     os_sr_t sr;
1254*042d53a7SEvalZero 
1255*042d53a7SEvalZero     /* Stop the phy */
1256*042d53a7SEvalZero     ble_phy_disable();
1257*042d53a7SEvalZero 
1258*042d53a7SEvalZero     /* Stop any wait for response timer */
1259*042d53a7SEvalZero     OS_ENTER_CRITICAL(sr);
1260*042d53a7SEvalZero     ble_ll_wfr_disable();
1261*042d53a7SEvalZero     ble_ll_sched_stop();
1262*042d53a7SEvalZero     OS_EXIT_CRITICAL(sr);
1263*042d53a7SEvalZero 
1264*042d53a7SEvalZero     /* Stop any scanning */
1265*042d53a7SEvalZero     ble_ll_scan_reset();
1266*042d53a7SEvalZero 
1267*042d53a7SEvalZero     /* Stop any advertising */
1268*042d53a7SEvalZero     ble_ll_adv_reset();
1269*042d53a7SEvalZero 
1270*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE)
1271*042d53a7SEvalZero     ble_ll_dtm_reset();
1272*042d53a7SEvalZero #endif
1273*042d53a7SEvalZero 
1274*042d53a7SEvalZero     /* FLush all packets from Link layer queues */
1275*042d53a7SEvalZero     ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q);
1276*042d53a7SEvalZero     ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_rx_pkt_q);
1277*042d53a7SEvalZero 
1278*042d53a7SEvalZero     /* Reset LL stats */
1279*042d53a7SEvalZero     STATS_RESET(ble_ll_stats);
1280*042d53a7SEvalZero 
1281*042d53a7SEvalZero     /* Reset any preferred PHYs */
1282*042d53a7SEvalZero     g_ble_ll_data.ll_pref_tx_phys = 0;
1283*042d53a7SEvalZero     g_ble_ll_data.ll_pref_rx_phys = 0;
1284*042d53a7SEvalZero 
1285*042d53a7SEvalZero     /* Reset connection module */
1286*042d53a7SEvalZero     ble_ll_conn_module_reset();
1287*042d53a7SEvalZero 
1288*042d53a7SEvalZero     /* All this does is re-initialize the event masks so call the hci init */
1289*042d53a7SEvalZero     ble_ll_hci_init();
1290*042d53a7SEvalZero 
1291*042d53a7SEvalZero     /* Reset scheduler */
1292*042d53a7SEvalZero     ble_ll_sched_init();
1293*042d53a7SEvalZero 
1294*042d53a7SEvalZero     /* Set state to standby */
1295*042d53a7SEvalZero     ble_ll_state_set(BLE_LL_STATE_STANDBY);
1296*042d53a7SEvalZero 
1297*042d53a7SEvalZero #ifdef BLE_XCVR_RFCLK
1298*042d53a7SEvalZero     /* Stops rf clock and rfclock timer */
1299*042d53a7SEvalZero     ble_ll_xcvr_rfclk_stop();
1300*042d53a7SEvalZero #endif
1301*042d53a7SEvalZero 
1302*042d53a7SEvalZero     /* Reset our random address */
1303*042d53a7SEvalZero     memset(g_random_addr, 0, BLE_DEV_ADDR_LEN);
1304*042d53a7SEvalZero 
1305*042d53a7SEvalZero     /* Clear the whitelist */
1306*042d53a7SEvalZero     ble_ll_whitelist_clear();
1307*042d53a7SEvalZero 
1308*042d53a7SEvalZero     /* Reset resolving list */
1309*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1310*042d53a7SEvalZero     ble_ll_resolv_list_reset();
1311*042d53a7SEvalZero #endif
1312*042d53a7SEvalZero 
1313*042d53a7SEvalZero     /* Re-initialize the PHY */
1314*042d53a7SEvalZero     rc = ble_phy_init();
1315*042d53a7SEvalZero 
1316*042d53a7SEvalZero     return rc;
1317*042d53a7SEvalZero }
1318*042d53a7SEvalZero 
1319*042d53a7SEvalZero static void
ble_ll_seed_prng(void)1320*042d53a7SEvalZero ble_ll_seed_prng(void)
1321*042d53a7SEvalZero {
1322*042d53a7SEvalZero     uint32_t seed;
1323*042d53a7SEvalZero     int i;
1324*042d53a7SEvalZero 
1325*042d53a7SEvalZero     /* Seed random number generator with least significant bytes of device
1326*042d53a7SEvalZero      * address.
1327*042d53a7SEvalZero      */
1328*042d53a7SEvalZero     seed = 0;
1329*042d53a7SEvalZero     for (i = 0; i < 4; ++i) {
1330*042d53a7SEvalZero         seed |= g_dev_addr[i];
1331*042d53a7SEvalZero         seed <<= 8;
1332*042d53a7SEvalZero     }
1333*042d53a7SEvalZero     srand(seed);
1334*042d53a7SEvalZero }
1335*042d53a7SEvalZero 
1336*042d53a7SEvalZero uint32_t
ble_ll_pdu_tx_time_get(uint16_t payload_len,int phy_mode)1337*042d53a7SEvalZero ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode)
1338*042d53a7SEvalZero {
1339*042d53a7SEvalZero     uint32_t usecs;
1340*042d53a7SEvalZero 
1341*042d53a7SEvalZero #if (BLE_LL_BT5_PHY_SUPPORTED)
1342*042d53a7SEvalZero     if (phy_mode == BLE_PHY_MODE_1M) {
1343*042d53a7SEvalZero         /* 8 usecs per byte */
1344*042d53a7SEvalZero         usecs = payload_len << 3;
1345*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_2M) {
1346*042d53a7SEvalZero         /* 4 usecs per byte */
1347*042d53a7SEvalZero         usecs = payload_len << 2;
1348*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_CODED_125KBPS) {
1349*042d53a7SEvalZero         /* S=8 => 8 * 8 = 64 usecs per byte */
1350*042d53a7SEvalZero         usecs = payload_len << 6;
1351*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_CODED_500KBPS) {
1352*042d53a7SEvalZero         /* S=2 => 2 * 8 = 16 usecs per byte */
1353*042d53a7SEvalZero         usecs = payload_len << 4;
1354*042d53a7SEvalZero     } else {
1355*042d53a7SEvalZero         BLE_LL_ASSERT(0);
1356*042d53a7SEvalZero     }
1357*042d53a7SEvalZero 
1358*042d53a7SEvalZero     usecs += g_ble_ll_pdu_header_tx_time[phy_mode];
1359*042d53a7SEvalZero #else
1360*042d53a7SEvalZero     usecs = (((payload_len) + BLE_LL_PDU_HDR_LEN + BLE_LL_ACC_ADDR_LEN
1361*042d53a7SEvalZero             + BLE_LL_PREAMBLE_LEN + BLE_LL_CRC_LEN) << 3);
1362*042d53a7SEvalZero #endif
1363*042d53a7SEvalZero 
1364*042d53a7SEvalZero     return usecs;
1365*042d53a7SEvalZero }
1366*042d53a7SEvalZero 
1367*042d53a7SEvalZero uint16_t
ble_ll_pdu_max_tx_octets_get(uint32_t usecs,int phy_mode)1368*042d53a7SEvalZero ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode)
1369*042d53a7SEvalZero {
1370*042d53a7SEvalZero     uint32_t header_tx_time;
1371*042d53a7SEvalZero     uint16_t octets;
1372*042d53a7SEvalZero 
1373*042d53a7SEvalZero     BLE_LL_ASSERT(phy_mode < BLE_PHY_NUM_MODE);
1374*042d53a7SEvalZero 
1375*042d53a7SEvalZero     header_tx_time = g_ble_ll_pdu_header_tx_time[phy_mode];
1376*042d53a7SEvalZero 
1377*042d53a7SEvalZero     /*
1378*042d53a7SEvalZero      * Current conn max tx time can be too short to even send a packet header
1379*042d53a7SEvalZero      * and this can happen if we changed connection form uncoded to coded phy.
1380*042d53a7SEvalZero      * However, the lower bound for conn max tx time (all of them) depends on
1381*042d53a7SEvalZero      * current phy (uncoded/coded) but it always allows to send at least 27
1382*042d53a7SEvalZero      * bytes of payload thus we alwyas return at least 27 from here.
1383*042d53a7SEvalZero      *
1384*042d53a7SEvalZero      * Reference:
1385*042d53a7SEvalZero      * Core v5.0, Vol 6, Part B, section 4.5.10
1386*042d53a7SEvalZero      * see connEffectiveMaxTxTime and connEffectiveMaxRxTime definitions
1387*042d53a7SEvalZero      */
1388*042d53a7SEvalZero 
1389*042d53a7SEvalZero     if (usecs < header_tx_time) {
1390*042d53a7SEvalZero         return 27;
1391*042d53a7SEvalZero     }
1392*042d53a7SEvalZero 
1393*042d53a7SEvalZero     usecs -= header_tx_time;
1394*042d53a7SEvalZero 
1395*042d53a7SEvalZero     if (phy_mode == BLE_PHY_MODE_1M) {
1396*042d53a7SEvalZero         /* 8 usecs per byte */
1397*042d53a7SEvalZero         octets = usecs >> 3;
1398*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_2M) {
1399*042d53a7SEvalZero         /* 4 usecs per byte */
1400*042d53a7SEvalZero         octets = usecs >> 2;
1401*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_CODED_125KBPS) {
1402*042d53a7SEvalZero         /* S=8 => 8 * 8 = 64 usecs per byte */
1403*042d53a7SEvalZero         octets = usecs >> 6;
1404*042d53a7SEvalZero     } else if (phy_mode == BLE_PHY_MODE_CODED_500KBPS) {
1405*042d53a7SEvalZero         /* S=2 => 2 * 8 = 16 usecs per byte */
1406*042d53a7SEvalZero         octets = usecs >> 4;
1407*042d53a7SEvalZero     } else {
1408*042d53a7SEvalZero         BLE_LL_ASSERT(0);
1409*042d53a7SEvalZero     }
1410*042d53a7SEvalZero 
1411*042d53a7SEvalZero     /* see comment at the beginning */
1412*042d53a7SEvalZero     return max(27, octets);
1413*042d53a7SEvalZero }
1414*042d53a7SEvalZero 
1415*042d53a7SEvalZero /**
1416*042d53a7SEvalZero  * Initialize the Link Layer. Should be called only once
1417*042d53a7SEvalZero  *
1418*042d53a7SEvalZero  * @return int
1419*042d53a7SEvalZero  */
1420*042d53a7SEvalZero void
ble_ll_init(void)1421*042d53a7SEvalZero ble_ll_init(void)
1422*042d53a7SEvalZero {
1423*042d53a7SEvalZero     int rc;
1424*042d53a7SEvalZero     uint32_t features;
1425*042d53a7SEvalZero #ifdef BLE_XCVR_RFCLK
1426*042d53a7SEvalZero     uint32_t xtal_ticks;
1427*042d53a7SEvalZero #endif
1428*042d53a7SEvalZero     ble_addr_t addr;
1429*042d53a7SEvalZero     struct ble_ll_obj *lldata;
1430*042d53a7SEvalZero 
1431*042d53a7SEvalZero     /* Ensure this function only gets called by sysinit. */
1432*042d53a7SEvalZero     SYSINIT_ASSERT_ACTIVE();
1433*042d53a7SEvalZero 
1434*042d53a7SEvalZero     ble_ll_trace_init();
1435*042d53a7SEvalZero     ble_phy_trace_init();
1436*042d53a7SEvalZero 
1437*042d53a7SEvalZero     /* Retrieve the public device address if not set by syscfg */
1438*042d53a7SEvalZero     memcpy(&addr.val[0], MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR, BLE_DEV_ADDR_LEN);
1439*042d53a7SEvalZero     if (!memcmp(&addr.val[0], ((ble_addr_t *)BLE_ADDR_ANY)->val,
1440*042d53a7SEvalZero                 BLE_DEV_ADDR_LEN)) {
1441*042d53a7SEvalZero         rc = ble_hw_get_public_addr(&addr);
1442*042d53a7SEvalZero         if (!rc) {
1443*042d53a7SEvalZero             memcpy(g_dev_addr, &addr.val[0], BLE_DEV_ADDR_LEN);
1444*042d53a7SEvalZero         }
1445*042d53a7SEvalZero     } else {
1446*042d53a7SEvalZero         memcpy(g_dev_addr, &addr.val[0], BLE_DEV_ADDR_LEN);
1447*042d53a7SEvalZero     }
1448*042d53a7SEvalZero 
1449*042d53a7SEvalZero #ifdef BLE_XCVR_RFCLK
1450*042d53a7SEvalZero     /* Settling time of crystal, in ticks */
1451*042d53a7SEvalZero     xtal_ticks = MYNEWT_VAL(BLE_XTAL_SETTLE_TIME);
1452*042d53a7SEvalZero     BLE_LL_ASSERT(xtal_ticks != 0);
1453*042d53a7SEvalZero     g_ble_ll_data.ll_xtal_ticks = os_cputime_usecs_to_ticks(xtal_ticks);
1454*042d53a7SEvalZero 
1455*042d53a7SEvalZero     /* Initialize rf clock timer */
1456*042d53a7SEvalZero     os_cputime_timer_init(&g_ble_ll_data.ll_rfclk_timer,
1457*042d53a7SEvalZero                           ble_ll_xcvr_rfclk_timer_exp, NULL);
1458*042d53a7SEvalZero 
1459*042d53a7SEvalZero #endif
1460*042d53a7SEvalZero 
1461*042d53a7SEvalZero     /* Get pointer to global data object */
1462*042d53a7SEvalZero     lldata = &g_ble_ll_data;
1463*042d53a7SEvalZero 
1464*042d53a7SEvalZero     /* Set acl pkt size and number */
1465*042d53a7SEvalZero     lldata->ll_num_acl_pkts = MYNEWT_VAL(BLE_ACL_BUF_COUNT);
1466*042d53a7SEvalZero     lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_ACL_BUF_SIZE);
1467*042d53a7SEvalZero 
1468*042d53a7SEvalZero     /*
1469*042d53a7SEvalZero      * XXX RIOT ties event queue to a thread which initialized it so we need to
1470*042d53a7SEvalZero      * create event queue in LL task, not in general init function. This can
1471*042d53a7SEvalZero      * lead to some races between host and LL so for now let us have it as a
1472*042d53a7SEvalZero      * hack for RIOT where races can be avoided by proper initialization inside
1473*042d53a7SEvalZero      * package.
1474*042d53a7SEvalZero      */
1475*042d53a7SEvalZero #ifndef RIOT_VERSION
1476*042d53a7SEvalZero     /* Initialize eventq */
1477*042d53a7SEvalZero     ble_npl_eventq_init(&lldata->ll_evq);
1478*042d53a7SEvalZero #endif
1479*042d53a7SEvalZero 
1480*042d53a7SEvalZero     /* Initialize the transmit (from host) and receive (from phy) queues */
1481*042d53a7SEvalZero     STAILQ_INIT(&lldata->ll_tx_pkt_q);
1482*042d53a7SEvalZero     STAILQ_INIT(&lldata->ll_rx_pkt_q);
1483*042d53a7SEvalZero 
1484*042d53a7SEvalZero     /* Initialize transmit (from host) and receive packet (from phy) event */
1485*042d53a7SEvalZero     ble_npl_event_init(&lldata->ll_rx_pkt_ev, ble_ll_event_rx_pkt, NULL);
1486*042d53a7SEvalZero     ble_npl_event_init(&lldata->ll_tx_pkt_ev, ble_ll_event_tx_pkt, NULL);
1487*042d53a7SEvalZero 
1488*042d53a7SEvalZero     /* Initialize data buffer overflow event and completed packets */
1489*042d53a7SEvalZero     ble_npl_event_init(&lldata->ll_dbuf_overflow_ev, ble_ll_event_dbuf_overflow, NULL);
1490*042d53a7SEvalZero     ble_npl_event_init(&lldata->ll_comp_pkt_ev, ble_ll_event_comp_pkts, NULL);
1491*042d53a7SEvalZero 
1492*042d53a7SEvalZero     /* Initialize the HW error timer */
1493*042d53a7SEvalZero     ble_npl_callout_init(&g_ble_ll_data.ll_hw_err_timer,
1494*042d53a7SEvalZero                          &g_ble_ll_data.ll_evq,
1495*042d53a7SEvalZero                          ble_ll_hw_err_timer_cb,
1496*042d53a7SEvalZero                          NULL);
1497*042d53a7SEvalZero 
1498*042d53a7SEvalZero     /* Initialize LL HCI */
1499*042d53a7SEvalZero     ble_ll_hci_init();
1500*042d53a7SEvalZero 
1501*042d53a7SEvalZero     /* Init the scheduler */
1502*042d53a7SEvalZero     ble_ll_sched_init();
1503*042d53a7SEvalZero 
1504*042d53a7SEvalZero     /* Initialize advertiser */
1505*042d53a7SEvalZero     ble_ll_adv_init();
1506*042d53a7SEvalZero 
1507*042d53a7SEvalZero     /* Initialize a scanner */
1508*042d53a7SEvalZero     ble_ll_scan_init();
1509*042d53a7SEvalZero 
1510*042d53a7SEvalZero     /* Initialize the connection module */
1511*042d53a7SEvalZero     ble_ll_conn_module_init();
1512*042d53a7SEvalZero 
1513*042d53a7SEvalZero     /* Set the supported features. NOTE: we always support extended reject. */
1514*042d53a7SEvalZero     features = BLE_LL_FEAT_EXTENDED_REJ;
1515*042d53a7SEvalZero 
1516*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
1517*042d53a7SEvalZero     features |= BLE_LL_FEAT_DATA_LEN_EXT;
1518*042d53a7SEvalZero #endif
1519*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_CONN_PARAM_REQ) == 1)
1520*042d53a7SEvalZero     features |= BLE_LL_FEAT_CONN_PARM_REQ;
1521*042d53a7SEvalZero #endif
1522*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG) == 1)
1523*042d53a7SEvalZero     features |= BLE_LL_FEAT_SLAVE_INIT;
1524*042d53a7SEvalZero #endif
1525*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
1526*042d53a7SEvalZero     features |= BLE_LL_FEAT_LE_ENCRYPTION;
1527*042d53a7SEvalZero #endif
1528*042d53a7SEvalZero 
1529*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1530*042d53a7SEvalZero     features |= (BLE_LL_FEAT_LL_PRIVACY | BLE_LL_FEAT_EXT_SCAN_FILT);
1531*042d53a7SEvalZero     ble_ll_resolv_init();
1532*042d53a7SEvalZero #endif
1533*042d53a7SEvalZero 
1534*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1)
1535*042d53a7SEvalZero     features |= BLE_LL_FEAT_LE_PING;
1536*042d53a7SEvalZero #endif
1537*042d53a7SEvalZero 
1538*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) == 1)
1539*042d53a7SEvalZero     features |= BLE_LL_FEAT_EXT_ADV;
1540*042d53a7SEvalZero #endif
1541*042d53a7SEvalZero 
1542*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
1543*042d53a7SEvalZero     /* CSA2 */
1544*042d53a7SEvalZero     features |= BLE_LL_FEAT_CSA2;
1545*042d53a7SEvalZero #endif
1546*042d53a7SEvalZero 
1547*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) == 1)
1548*042d53a7SEvalZero     features |= BLE_LL_FEAT_LE_2M_PHY;
1549*042d53a7SEvalZero #endif
1550*042d53a7SEvalZero 
1551*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) == 1)
1552*042d53a7SEvalZero     features |= BLE_LL_FEAT_LE_CODED_PHY;
1553*042d53a7SEvalZero #endif
1554*042d53a7SEvalZero 
1555*042d53a7SEvalZero     /* Initialize random number generation */
1556*042d53a7SEvalZero     ble_ll_rand_init();
1557*042d53a7SEvalZero 
1558*042d53a7SEvalZero     /* XXX: This really doesn't belong here, as the address probably has not
1559*042d53a7SEvalZero      * been set yet.
1560*042d53a7SEvalZero      */
1561*042d53a7SEvalZero     ble_ll_seed_prng();
1562*042d53a7SEvalZero 
1563*042d53a7SEvalZero     lldata->ll_supp_features = features;
1564*042d53a7SEvalZero 
1565*042d53a7SEvalZero #if MYNEWT
1566*042d53a7SEvalZero     /* Initialize the LL task */
1567*042d53a7SEvalZero     os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL,
1568*042d53a7SEvalZero                  MYNEWT_VAL(BLE_LL_PRIO), OS_WAIT_FOREVER, g_ble_ll_stack,
1569*042d53a7SEvalZero                  BLE_LL_STACK_SIZE);
1570*042d53a7SEvalZero #else
1571*042d53a7SEvalZero 
1572*042d53a7SEvalZero /*
1573*042d53a7SEvalZero  * For non-Mynewt OS it is required that OS creates task for LL and run LL
1574*042d53a7SEvalZero  * routine which is wrapped by nimble_port_ll_task_func().
1575*042d53a7SEvalZero  */
1576*042d53a7SEvalZero 
1577*042d53a7SEvalZero #endif
1578*042d53a7SEvalZero 
1579*042d53a7SEvalZero     rc = stats_init_and_reg(STATS_HDR(ble_ll_stats),
1580*042d53a7SEvalZero                             STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32),
1581*042d53a7SEvalZero                             STATS_NAME_INIT_PARMS(ble_ll_stats),
1582*042d53a7SEvalZero                             "ble_ll");
1583*042d53a7SEvalZero     SYSINIT_PANIC_ASSERT(rc == 0);
1584*042d53a7SEvalZero 
1585*042d53a7SEvalZero     ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL);
1586*042d53a7SEvalZero 
1587*042d53a7SEvalZero #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE)
1588*042d53a7SEvalZero     ble_ll_dtm_init();
1589*042d53a7SEvalZero #endif
1590*042d53a7SEvalZero }
1591