xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/controller/src/ble_ll_conn.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24 #include "syscfg/syscfg.h"
25 #include "os/os.h"
26 #include "os/os_cputime.h"
27 #include "nimble/ble.h"
28 #include "nimble/nimble_opt.h"
29 #include "nimble/hci_common.h"
30 #include "nimble/ble_hci_trans.h"
31 #include "ble/xcvr.h"
32 #include "controller/ble_ll.h"
33 #include "controller/ble_ll_hci.h"
34 #include "controller/ble_ll_scan.h"
35 #include "controller/ble_ll_whitelist.h"
36 #include "controller/ble_ll_sched.h"
37 #include "controller/ble_ll_ctrl.h"
38 #include "controller/ble_ll_resolv.h"
39 #include "controller/ble_ll_adv.h"
40 #include "controller/ble_ll_trace.h"
41 #include "controller/ble_phy.h"
42 #include "controller/ble_hw.h"
43 #include "ble_ll_conn_priv.h"
44 
45 #if (BLETEST_THROUGHPUT_TEST == 1)
46 extern void bletest_completed_pkt(uint16_t handle);
47 #endif
48 
49 /* XXX TODO
50  * 1) I think if we are initiating and we already have a connection with
51  * a device that we will still try and connect to it. Fix this.
52  *  -> This is true. There are a couple things to do
53  *      i) When a connection create is issued, if we already are connected
54  *      deny it. BLE ERROR = 0x0B (ACL connection exists).
55  *      ii) If we receive an advertisement while initiating and want to send
56  *      a connect request to the device, make sure we dont have it.
57  *      iii) I think I need to do something like this: I am initiating and
58  *      advertising. Suppose the device I want to connect to sends me a connect
59  *      request because I am advertising? What happens to connection? Deal
60  *      with this!
61  *
62  * 2) Make sure we check incoming data packets for size and all that. You
63  * know, supported octets and all that. For both rx and tx.
64  *
65  * 3) Make sure we are setting the schedule end time properly for both slave
66  * and master. We should just set this to the end of the connection event.
67  * We might want to guarantee a IFS time as well since the next event needs
68  * to be scheduled prior to the start of the event to account for the time it
69  * takes to get a frame ready (which is pretty much the IFS time).
70  *
71  * 4) looks like the current code will allow the 1st packet in a
72  * connection to extend past the end of the allocated connection end
73  * time. That is not good. Need to deal with that. Need to extend connection
74  * end time.
75  *
76  * 6) Use error code 0x3E correctly! Connection failed to establish. If you
77  * read the LE connection complete event, it says that if the connection
78  * fails to be established that the connection complete event gets sent to
79  * the host that issued the create connection. Need to resolve this.
80  *
81  * 7) How does peer address get set if we are using whitelist? Look at filter
82  * policy and make sure you are doing this correctly.
83  *
84  * 8) Right now I use a fixed definition for required slots. CHange this.
85  *
86  * 10) See what connection state machine elements are purely master and
87  * purely slave. We can make a union of them.
88  *
89  * 11) Not sure I am dealing with the connection terminate timeout perfectly.
90  * I may extend a connection event too long although if it is always in terms
91  * of connection events I am probably fine. Checking at end that the next
92  * connection event will occur past terminate timeould would be fine.
93  *
94  * 12) When a slave receives a data packet in a connection it has to send a
95  * response. Well, it should. If this packet will overrun the next scheduled
96  * event, what should we do? Transmit anyway? Not transmit? For now, we just
97  * transmit.
98  *
99  * 32kHz crystal
100  * 1) When scheduling, I need to make sure I have time between
101  * this one and the next. Should I deal with this in the sched. Or
102  * is this basically accounted for given a slot? I really just need to
103  * make sure everything is over N ticks before the next sched start!
104  * Just add to end time?
105  *
106  * 2) I think one way to handle the problem of losing up to a microsecond
107  * every time we call ble_ll_conn_next_event in a loop is to do everything by
108  * keeping track of last anchor point. Would need last anchor usecs too. I guess
109  * we could also keep last anchor usecs as a uint32 or something and when we
110  * do the next event keep track of the residual using a different ticks to
111  * usecs calculation. Not sure.
112  */
113 
114 /*
115  * XXX: How should we deal with a late connection event? We need to determine
116  * what we want to do under the following cases:
117  *  1) The current connection event has not ended but a schedule item starts
118  */
119 
120 /* This is a dummy structure we use for the empty PDU */
121 struct ble_ll_empty_pdu
122 {
123     struct os_mbuf om;
124     struct os_mbuf_pkthdr pkt_hdr;
125     struct ble_mbuf_hdr ble_hdr;
126 };
127 
128 /* We cannot have more than 254 connections given our current implementation */
129 #if (MYNEWT_VAL(BLE_MAX_CONNECTIONS) >= 255)
130     #error "Maximum # of connections is 254"
131 #endif
132 
133 /* Sleep clock accuracy table (in ppm) */
134 static const uint16_t g_ble_sca_ppm_tbl[8] =
135 {
136     500, 250, 150, 100, 75, 50, 30, 20
137 };
138 
139 /* Global connection complete event. Used when initiating */
140 uint8_t *g_ble_ll_conn_comp_ev;
141 
142 /* Global LL connection parameters */
143 struct ble_ll_conn_global_params g_ble_ll_conn_params;
144 
145 /* Pointer to connection state machine we are trying to create */
146 struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
147 
148 /* Pointer to current connection */
149 struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm;
150 
151 /* Connection state machine array */
152 struct ble_ll_conn_sm g_ble_ll_conn_sm[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
153 
154 /* List of active connections */
155 struct ble_ll_conn_active_list g_ble_ll_conn_active_list;
156 
157 /* List of free connections */
158 struct ble_ll_conn_free_list g_ble_ll_conn_free_list;
159 
160 STATS_SECT_START(ble_ll_conn_stats)
161     STATS_SECT_ENTRY(cant_set_sched)
162     STATS_SECT_ENTRY(conn_ev_late)
163     STATS_SECT_ENTRY(wfr_expirations)
164     STATS_SECT_ENTRY(handle_not_found)
165     STATS_SECT_ENTRY(no_conn_sm)
166     STATS_SECT_ENTRY(no_free_conn_sm)
167     STATS_SECT_ENTRY(rx_data_pdu_no_conn)
168     STATS_SECT_ENTRY(rx_data_pdu_bad_aa)
169     STATS_SECT_ENTRY(slave_rxd_bad_conn_req_params)
170     STATS_SECT_ENTRY(slave_ce_failures)
171     STATS_SECT_ENTRY(data_pdu_rx_dup)
172     STATS_SECT_ENTRY(data_pdu_txg)
173     STATS_SECT_ENTRY(data_pdu_txf)
174     STATS_SECT_ENTRY(conn_req_txd)
175     STATS_SECT_ENTRY(l2cap_enqueued)
176     STATS_SECT_ENTRY(rx_ctrl_pdus)
177     STATS_SECT_ENTRY(rx_l2cap_pdus)
178     STATS_SECT_ENTRY(rx_l2cap_bytes)
179     STATS_SECT_ENTRY(rx_malformed_ctrl_pdus)
180     STATS_SECT_ENTRY(rx_bad_llid)
181     STATS_SECT_ENTRY(tx_ctrl_pdus)
182     STATS_SECT_ENTRY(tx_ctrl_bytes)
183     STATS_SECT_ENTRY(tx_l2cap_pdus)
184     STATS_SECT_ENTRY(tx_l2cap_bytes)
185     STATS_SECT_ENTRY(tx_empty_pdus)
186     STATS_SECT_ENTRY(mic_failures)
187 STATS_SECT_END
188 STATS_SECT_DECL(ble_ll_conn_stats) ble_ll_conn_stats;
189 
190 STATS_NAME_START(ble_ll_conn_stats)
191     STATS_NAME(ble_ll_conn_stats, cant_set_sched)
192     STATS_NAME(ble_ll_conn_stats, conn_ev_late)
193     STATS_NAME(ble_ll_conn_stats, wfr_expirations)
194     STATS_NAME(ble_ll_conn_stats, handle_not_found)
195     STATS_NAME(ble_ll_conn_stats, no_conn_sm)
196     STATS_NAME(ble_ll_conn_stats, no_free_conn_sm)
197     STATS_NAME(ble_ll_conn_stats, rx_data_pdu_no_conn)
198     STATS_NAME(ble_ll_conn_stats, rx_data_pdu_bad_aa)
199     STATS_NAME(ble_ll_conn_stats, slave_rxd_bad_conn_req_params)
200     STATS_NAME(ble_ll_conn_stats, slave_ce_failures)
201     STATS_NAME(ble_ll_conn_stats, data_pdu_rx_dup)
202     STATS_NAME(ble_ll_conn_stats, data_pdu_txg)
203     STATS_NAME(ble_ll_conn_stats, data_pdu_txf)
204     STATS_NAME(ble_ll_conn_stats, conn_req_txd)
205     STATS_NAME(ble_ll_conn_stats, l2cap_enqueued)
206     STATS_NAME(ble_ll_conn_stats, rx_ctrl_pdus)
207     STATS_NAME(ble_ll_conn_stats, rx_l2cap_pdus)
208     STATS_NAME(ble_ll_conn_stats, rx_l2cap_bytes)
209     STATS_NAME(ble_ll_conn_stats, rx_malformed_ctrl_pdus)
210     STATS_NAME(ble_ll_conn_stats, rx_bad_llid)
211     STATS_NAME(ble_ll_conn_stats, tx_ctrl_pdus)
212     STATS_NAME(ble_ll_conn_stats, tx_ctrl_bytes)
213     STATS_NAME(ble_ll_conn_stats, tx_l2cap_pdus)
214     STATS_NAME(ble_ll_conn_stats, tx_l2cap_bytes)
215     STATS_NAME(ble_ll_conn_stats, tx_empty_pdus)
216     STATS_NAME(ble_ll_conn_stats, mic_failures)
217 STATS_NAME_END(ble_ll_conn_stats)
218 
219 static void ble_ll_conn_event_end(struct ble_npl_event *ev);
220 
221 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
222 /**
223  * Checks to see if we should start a PHY update procedure
224  *
225  * If current phy is not one of the preferred we need to start control
226  * procedure.
227  *
228  * XXX: we could also decide to change the PHY if RSSI is really good
229  * and we are currently at 1Mbps or lower data rate and we could use
230  * a higher data rate.
231  *
232  * @param connsm
233  * @return 0: success; -1: no phy update procedure started
234  */
235 int
ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm * csm)236 ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *csm)
237 {
238     int rc;
239 
240     /* If no host preferences or  */
241     if (((csm->phy_data.host_pref_tx_phys_mask == 0) &&
242          (csm->phy_data.host_pref_rx_phys_mask == 0)) ||
243         ((csm->phy_data.host_pref_tx_phys_mask & CONN_CUR_TX_PHY_MASK(csm)) &&
244          (csm->phy_data.host_pref_rx_phys_mask & CONN_CUR_RX_PHY_MASK(csm)))) {
245         rc = -1;
246     } else {
247         csm->phy_data.req_pref_tx_phys_mask = csm->phy_data.host_pref_tx_phys_mask;
248         csm->phy_data.req_pref_rx_phys_mask = csm->phy_data.host_pref_rx_phys_mask;
249         ble_ll_ctrl_proc_start(csm, BLE_LL_CTRL_PROC_PHY_UPDATE);
250         rc = 0;
251     }
252 
253     return rc;
254 }
255 #endif
256 
257 static void
ble_ll_conn_calc_itvl_ticks(struct ble_ll_conn_sm * connsm)258 ble_ll_conn_calc_itvl_ticks(struct ble_ll_conn_sm *connsm)
259 {
260     uint32_t ticks;
261     uint32_t usecs;
262 
263     /*
264      * Precalculate the number of ticks and remaining microseconds for
265      * the connection interval
266      */
267     usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
268     ticks = os_cputime_usecs_to_ticks(usecs);
269     connsm->conn_itvl_usecs = (uint8_t)(usecs -
270                                         os_cputime_ticks_to_usecs(ticks));
271     if (connsm->conn_itvl_usecs == 31) {
272         connsm->conn_itvl_usecs = 0;
273         ++ticks;
274     }
275     connsm->conn_itvl_ticks = ticks;
276 }
277 
278 /**
279  * Get the event buffer allocated to send the connection complete event
280  * when we are initiating.
281  *
282  * @return uint8_t*
283  */
284 static uint8_t *
ble_ll_init_get_conn_comp_ev(void)285 ble_ll_init_get_conn_comp_ev(void)
286 {
287     uint8_t *evbuf;
288 
289     evbuf = g_ble_ll_conn_comp_ev;
290     BLE_LL_ASSERT(evbuf != NULL);
291     g_ble_ll_conn_comp_ev = NULL;
292 
293     return evbuf;
294 }
295 
296 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
297 /**
298  * Called to determine if the received PDU is an empty PDU or not.
299  */
300 static int
ble_ll_conn_is_empty_pdu(uint8_t * rxbuf)301 ble_ll_conn_is_empty_pdu(uint8_t *rxbuf)
302 {
303     int rc;
304     uint8_t llid;
305 
306     llid = rxbuf[0] & BLE_LL_DATA_HDR_LLID_MASK;
307     if ((llid == BLE_LL_LLID_DATA_FRAG) && (rxbuf[1] == 0)) {
308         rc = 1;
309     } else {
310         rc = 0;
311     }
312     return rc;
313 }
314 #endif
315 
316 /**
317  * Called to return the currently running connection state machine end time.
318  * Always called when interrupts are disabled.
319  *
320  * @return int 0: s1 is not least recently used. 1: s1 is least recently used
321  */
322 int
ble_ll_conn_is_lru(struct ble_ll_conn_sm * s1,struct ble_ll_conn_sm * s2)323 ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2)
324 {
325     int rc;
326 
327     /* Set time that we last serviced the schedule */
328     if ((int32_t)(s1->last_scheduled - s2->last_scheduled) < 0) {
329         rc = 1;
330     } else {
331         rc = 0;
332     }
333 
334     return rc;
335 }
336 
337 /**
338  * Called to return the currently running connection state machine end time.
339  * Always called when interrupts are disabled.
340  *
341  * @return uint32_t
342  */
343 uint32_t
ble_ll_conn_get_ce_end_time(void)344 ble_ll_conn_get_ce_end_time(void)
345 {
346     uint32_t ce_end_time;
347 
348     if (g_ble_ll_conn_cur_sm) {
349         ce_end_time = g_ble_ll_conn_cur_sm->ce_end_time;
350     } else {
351         ce_end_time = os_cputime_get32();
352     }
353     return ce_end_time;
354 }
355 
356 /**
357  * Called when the current connection state machine is no longer being used.
358  * This function will:
359  *  -> Disable the PHY, which will prevent any transmit/receive interrupts.
360  *  -> Disable the wait for response timer, if running.
361  *  -> Remove the connection state machine from the scheduler.
362  *  -> Sets the Link Layer state to standby.
363  *  -> Sets the current state machine to NULL.
364  *
365  *  NOTE: the ordering of these function calls is important! We have to stop
366  *  the PHY and remove the schedule item before we can set the state to
367  *  standby and set the current state machine pointer to NULL.
368  */
369 static void
ble_ll_conn_current_sm_over(struct ble_ll_conn_sm * connsm)370 ble_ll_conn_current_sm_over(struct ble_ll_conn_sm *connsm)
371 {
372     /* Disable the PHY */
373     ble_phy_disable();
374 
375     /* Disable the wfr timer */
376     ble_ll_wfr_disable();
377 
378     /* Link-layer is in standby state now */
379     ble_ll_state_set(BLE_LL_STATE_STANDBY);
380 
381     /* Set current LL connection to NULL */
382     g_ble_ll_conn_cur_sm = NULL;
383 
384     /*
385      * NOTE: the connection state machine may be NULL if we are calling
386      * this when we are ending the connection. In that case, there is no
387      * need to post to the LL the connection event end event
388      */
389     if (connsm) {
390         ble_ll_event_send(&connsm->conn_ev_end);
391     }
392 }
393 
394 /**
395  * Given a handle, find an active connection matching the handle
396  *
397  * @param handle
398  *
399  * @return struct ble_ll_conn_sm*
400  */
401 struct ble_ll_conn_sm *
ble_ll_conn_find_active_conn(uint16_t handle)402 ble_ll_conn_find_active_conn(uint16_t handle)
403 {
404     struct ble_ll_conn_sm *connsm;
405 
406     connsm = NULL;
407     if ((handle != 0) && (handle <= MYNEWT_VAL(BLE_MAX_CONNECTIONS))) {
408         connsm = &g_ble_ll_conn_sm[handle - 1];
409         if (connsm->conn_state == BLE_LL_CONN_STATE_IDLE) {
410             connsm = NULL;
411         }
412     }
413     return connsm;
414 }
415 
416 /**
417  * Get a connection state machine.
418  */
419 struct ble_ll_conn_sm *
ble_ll_conn_sm_get(void)420 ble_ll_conn_sm_get(void)
421 {
422     struct ble_ll_conn_sm *connsm;
423 
424     connsm = STAILQ_FIRST(&g_ble_ll_conn_free_list);
425     if (connsm) {
426         STAILQ_REMOVE_HEAD(&g_ble_ll_conn_free_list, free_stqe);
427     } else {
428         STATS_INC(ble_ll_conn_stats, no_free_conn_sm);
429     }
430 
431     return connsm;
432 }
433 
434 /**
435  * Calculate the amount of window widening for a given connection event. This
436  * is the amount of time that a slave has to account for when listening for
437  * the start of a connection event.
438  *
439  * @param connsm Pointer to connection state machine.
440  *
441  * @return uint32_t The current window widening amount (in microseconds)
442  */
443 uint32_t
ble_ll_conn_calc_window_widening(struct ble_ll_conn_sm * connsm)444 ble_ll_conn_calc_window_widening(struct ble_ll_conn_sm *connsm)
445 {
446     uint32_t total_sca_ppm;
447     uint32_t window_widening;
448     int32_t time_since_last_anchor;
449     uint32_t delta_msec;
450 
451     window_widening = 0;
452 
453     time_since_last_anchor = (int32_t)(connsm->anchor_point -
454                                        connsm->last_anchor_point);
455     if (time_since_last_anchor > 0) {
456         delta_msec = os_cputime_ticks_to_usecs(time_since_last_anchor) / 1000;
457         total_sca_ppm = g_ble_sca_ppm_tbl[connsm->master_sca] +
458             MYNEWT_VAL(BLE_LL_OUR_SCA);
459         window_widening = (total_sca_ppm * delta_msec) / 1000;
460     }
461 
462     return window_widening;
463 }
464 
465 /**
466  * Calculates the number of used channels in the channel map
467  *
468  * @param chmap
469  *
470  * @return uint8_t Number of used channels
471  */
472 uint8_t
ble_ll_conn_calc_used_chans(uint8_t * chmap)473 ble_ll_conn_calc_used_chans(uint8_t *chmap)
474 {
475     int i;
476     int j;
477     uint8_t mask;
478     uint8_t chanbyte;
479     uint8_t used_channels;
480 
481     used_channels = 0;
482     for (i = 0; i < BLE_LL_CONN_CHMAP_LEN; ++i) {
483         chanbyte = chmap[i];
484         if (chanbyte) {
485             if (chanbyte == 0xff) {
486                 used_channels += 8;
487             } else {
488                 mask = 0x01;
489                 for (j = 0; j < 8; ++j) {
490                     if (chanbyte & mask) {
491                         ++used_channels;
492                     }
493                     mask <<= 1;
494                 }
495             }
496         }
497     }
498     return used_channels;
499 }
500 
501 static uint32_t
ble_ll_conn_calc_access_addr(void)502 ble_ll_conn_calc_access_addr(void)
503 {
504     uint32_t aa;
505     uint16_t aa_low;
506     uint16_t aa_high;
507     uint32_t temp;
508     uint32_t mask;
509     uint32_t prev_bit;
510     uint8_t bits_diff;
511     uint8_t consecutive;
512     uint8_t transitions;
513     uint8_t ones;
514 
515     /* Calculate a random access address */
516     aa = 0;
517     while (1) {
518         /* Get two, 16-bit random numbers */
519         aa_low = rand() & 0xFFFF;
520         aa_high = rand() & 0xFFFF;
521 
522         /* All four bytes cannot be equal */
523         if (aa_low == aa_high) {
524             continue;
525         }
526 
527         /* Upper 6 bits must have 2 transitions */
528         temp = aa_high & 0xFC00;
529         if ((temp == 0) || (temp == 0xFC00)) {
530             continue;
531         }
532 
533         /* Cannot be access address or be 1 bit different */
534         aa = aa_high;
535         aa = (aa << 16) | aa_low;
536         bits_diff = 0;
537         temp = aa ^ BLE_ACCESS_ADDR_ADV;
538         for (mask = 0x00000001; mask != 0; mask <<= 1) {
539             if (mask & temp) {
540                 ++bits_diff;
541                 if (bits_diff > 1) {
542                     break;
543                 }
544             }
545         }
546         if (bits_diff <= 1) {
547             continue;
548         }
549 
550         /* Cannot have more than 24 transitions */
551         transitions = 0;
552         consecutive = 1;
553         ones = 0;
554         mask = 0x00000001;
555         while (mask < 0x80000000) {
556             prev_bit = aa & mask;
557             mask <<= 1;
558             if (mask & aa) {
559                 if (prev_bit == 0) {
560                     ++transitions;
561                     consecutive = 1;
562                 } else {
563                     ++consecutive;
564                 }
565             } else {
566                 if (prev_bit == 0) {
567                     ++consecutive;
568                 } else {
569                     ++transitions;
570                     consecutive = 1;
571                 }
572             }
573 
574             if (prev_bit) {
575                 ones++;
576             }
577 
578             /* 8 lsb should have at least three 1 */
579             if (mask == 0x00000100 && ones < 3) {
580                 break;
581             }
582 
583             /* 16 lsb should have no more than 11 transitions */
584             if (mask == 0x00010000 && transitions > 11) {
585                 break;
586             }
587 
588             /* This is invalid! */
589             if (consecutive > 6) {
590                 /* Make sure we always detect invalid sequence below */
591                 mask = 0;
592                 break;
593             }
594         }
595 
596         /* Invalid sequence found */
597         if (mask != 0x80000000) {
598             continue;
599         }
600 
601         /* Cannot be more than 24 transitions */
602         if (transitions > 24) {
603             continue;
604         }
605 
606         /* We have a valid access address */
607         break;
608     }
609     return aa;
610 }
611 
612 static uint8_t
ble_ll_conn_remapped_channel(uint8_t remap_index,const uint8_t * chanmap)613 ble_ll_conn_remapped_channel(uint8_t remap_index, const uint8_t *chanmap)
614 {
615     uint8_t cntr;
616     uint8_t mask;
617     uint8_t usable_chans;
618     uint8_t chan;
619     int i, j;
620 
621     /* NOTE: possible to build a map but this would use memory. For now,
622        we just calculate */
623     /* Iterate through channel map to find this channel */
624     chan = 0;
625     cntr = 0;
626     for (i = 0; i < BLE_LL_CONN_CHMAP_LEN; i++) {
627         usable_chans = chanmap[i];
628         if (usable_chans != 0) {
629             mask = 0x01;
630             for (j = 0; j < 8; j++) {
631                 if (usable_chans & mask) {
632                     if (cntr == remap_index) {
633                         return (chan + j);
634                     }
635                     ++cntr;
636                 }
637                 mask <<= 1;
638             }
639         }
640         chan += 8;
641     }
642 
643     /* we should never reach here */
644     BLE_LL_ASSERT(0);
645     return 0;
646 }
647 
648 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
649 static uint16_t
ble_ll_conn_csa2_perm(uint16_t in)650 ble_ll_conn_csa2_perm(uint16_t in)
651 {
652     uint16_t out = 0;
653     int i;
654 
655     for (i = 0; i < 8; i++) {
656         out |= ((in >> i) & 0x00000001) << (7 - i);
657     }
658 
659     for (i = 8; i < 16; i++) {
660         out |= ((in >> i) & 0x00000001) << (15 + 8 - i);
661     }
662 
663     return out;
664 }
665 
666 static uint16_t
ble_ll_conn_csa2_prng(uint16_t counter,uint16_t ch_id)667 ble_ll_conn_csa2_prng(uint16_t counter, uint16_t ch_id)
668 {
669     uint16_t prn_e;
670 
671     prn_e = counter ^ ch_id;
672 
673     prn_e = ble_ll_conn_csa2_perm(prn_e);
674     prn_e = (prn_e * 17) + ch_id;
675 
676     prn_e = ble_ll_conn_csa2_perm(prn_e);
677     prn_e = (prn_e * 17) + ch_id;
678 
679     prn_e = ble_ll_conn_csa2_perm(prn_e);
680     prn_e = (prn_e * 17) + ch_id;
681 
682     prn_e = prn_e ^ ch_id;
683 
684     return prn_e;
685 }
686 
687 static uint8_t
ble_ll_conn_calc_dci_csa2(struct ble_ll_conn_sm * conn)688 ble_ll_conn_calc_dci_csa2(struct ble_ll_conn_sm *conn)
689 {
690     uint16_t channel_unmapped;
691     uint8_t remap_index;
692 
693     uint16_t prn_e;
694     uint8_t bitpos;
695 
696     prn_e = ble_ll_conn_csa2_prng(conn->event_cntr, conn->channel_id);
697 
698     channel_unmapped = prn_e % 37;
699 
700     /*
701      * If unmapped channel is the channel index of a used channel it is used
702      * as channel index.
703      */
704     bitpos = 1 << (channel_unmapped & 0x07);
705     if (conn->chanmap[channel_unmapped >> 3] & bitpos) {
706         return channel_unmapped;
707     }
708 
709     remap_index = (conn->num_used_chans * prn_e) / 0x10000;
710 
711     return ble_ll_conn_remapped_channel(remap_index, conn->chanmap);
712 }
713 #endif
714 
715 static uint8_t
ble_ll_conn_calc_dci_csa1(struct ble_ll_conn_sm * conn)716 ble_ll_conn_calc_dci_csa1(struct ble_ll_conn_sm *conn)
717 {
718     uint8_t curchan;
719     uint8_t remap_index;
720     uint8_t bitpos;
721 
722     /* Get next unmapped channel */
723     curchan = conn->last_unmapped_chan + conn->hop_inc;
724     if (curchan > BLE_PHY_NUM_DATA_CHANS) {
725         curchan -= BLE_PHY_NUM_DATA_CHANS;
726     }
727 
728     /* Save unmapped channel */
729     conn->last_unmapped_chan = curchan;
730 
731     /* Is this a valid channel? */
732     bitpos = 1 << (curchan & 0x07);
733     if (conn->chanmap[curchan >> 3] & bitpos) {
734         return curchan;
735     }
736 
737     /* Calculate remap index */
738     remap_index = curchan % conn->num_used_chans;
739 
740     return ble_ll_conn_remapped_channel(remap_index, conn->chanmap);
741 }
742 
743 /**
744  * Determine data channel index to be used for the upcoming/current
745  * connection event
746  *
747  * @param conn
748  * @param latency Used only for CSA #1
749  *
750  * @return uint8_t
751  */
752 uint8_t
ble_ll_conn_calc_dci(struct ble_ll_conn_sm * conn,uint16_t latency)753 ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency)
754 {
755     uint8_t index;
756 
757 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
758     if (CONN_F_CSA2_SUPP(conn)) {
759         return ble_ll_conn_calc_dci_csa2(conn);
760     }
761 #endif
762 
763     index = conn->data_chan_index;
764 
765     while (latency > 0) {
766         index = ble_ll_conn_calc_dci_csa1(conn);
767         latency--;
768     }
769 
770     return index;
771 }
772 
773 /**
774  * Called when we are in the connection state and the wait for response timer
775  * fires off.
776  *
777  * Context: Interrupt
778  */
779 void
ble_ll_conn_wfr_timer_exp(void)780 ble_ll_conn_wfr_timer_exp(void)
781 {
782     struct ble_ll_conn_sm *connsm;
783 
784     connsm = g_ble_ll_conn_cur_sm;
785     ble_ll_conn_current_sm_over(connsm);
786     STATS_INC(ble_ll_conn_stats, wfr_expirations);
787 }
788 
789 void
ble_ll_conn_reset_pending_aux_conn_rsp(void)790 ble_ll_conn_reset_pending_aux_conn_rsp(void)
791 {
792 #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
793     return;
794 #endif
795     struct ble_ll_conn_sm *connsm;
796 
797     connsm = g_ble_ll_conn_create_sm;
798     if (!connsm) {
799         return;
800     }
801 
802     if (CONN_F_AUX_CONN_REQ(connsm)) {
803         STATS_INC(ble_ll_stats, aux_conn_rsp_err);
804         CONN_F_CONN_REQ_TXD(connsm) = 0;
805         CONN_F_AUX_CONN_REQ(connsm) = 0;
806         ble_ll_sched_rmv_elem(&connsm->conn_sch);
807         return;
808     }
809 
810     return;
811 }
812 
813 bool
ble_ll_conn_init_pending_aux_conn_rsp(void)814 ble_ll_conn_init_pending_aux_conn_rsp(void)
815 {
816 #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
817     return false;
818 #endif
819     struct ble_ll_conn_sm *connsm;
820 
821     connsm = g_ble_ll_conn_create_sm;
822     if (!connsm) {
823         return false;
824     }
825 
826     return CONN_F_AUX_CONN_REQ(connsm);
827 }
828 
829 void
ble_ll_conn_init_wfr_timer_exp(void)830 ble_ll_conn_init_wfr_timer_exp(void)
831 {
832 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
833     struct ble_ll_conn_sm *connsm;
834     struct ble_ll_scan_sm *scansm;
835 
836     connsm = g_ble_ll_conn_create_sm;
837     if (!connsm) {
838         return;
839     }
840 
841     ble_ll_conn_reset_pending_aux_conn_rsp();
842 
843     scansm = connsm->scansm;
844     if (scansm && scansm->cur_aux_data) {
845         if (ble_ll_scan_aux_data_unref(scansm->cur_aux_data)) {
846             ble_ll_scan_aux_data_unref(scansm->cur_aux_data);
847         }
848         scansm->cur_aux_data = NULL;
849         STATS_INC(ble_ll_stats, aux_missed_adv);
850         ble_ll_event_send(&scansm->scan_sched_ev);
851     }
852 
853     connsm->inita_identity_used = 0;
854 #endif
855 }
856 /**
857  * Callback for slave when it transmits a data pdu and the connection event
858  * ends after the transmission.
859  *
860  * Context: Interrupt
861  *
862  * @param sch
863  *
864  */
865 static void
ble_ll_conn_wait_txend(void * arg)866 ble_ll_conn_wait_txend(void *arg)
867 {
868     struct ble_ll_conn_sm *connsm;
869 
870     connsm = (struct ble_ll_conn_sm *)arg;
871     ble_ll_conn_current_sm_over(connsm);
872 }
873 
874 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
875 static void
ble_ll_conn_start_rx_encrypt(void * arg)876 ble_ll_conn_start_rx_encrypt(void *arg)
877 {
878     struct ble_ll_conn_sm *connsm;
879 
880     connsm = (struct ble_ll_conn_sm *)arg;
881     CONN_F_ENCRYPTED(connsm) = 1;
882     ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr,
883                            connsm->enc_data.iv,
884                            connsm->enc_data.enc_block.cipher_text,
885                            !CONN_IS_MASTER(connsm));
886 }
887 
888 static void
ble_ll_conn_start_rx_unencrypt(void * arg)889 ble_ll_conn_start_rx_unencrypt(void *arg)
890 {
891     struct ble_ll_conn_sm *connsm;
892 
893     connsm = (struct ble_ll_conn_sm *)arg;
894     CONN_F_ENCRYPTED(connsm) = 0;
895     ble_phy_encrypt_disable();
896 }
897 
898 static void
ble_ll_conn_txend_encrypt(void * arg)899 ble_ll_conn_txend_encrypt(void *arg)
900 {
901     struct ble_ll_conn_sm *connsm;
902 
903     connsm = (struct ble_ll_conn_sm *)arg;
904     CONN_F_ENCRYPTED(connsm) = 1;
905     ble_ll_conn_current_sm_over(connsm);
906 }
907 
908 static void
ble_ll_conn_rxend_unencrypt(void * arg)909 ble_ll_conn_rxend_unencrypt(void *arg)
910 {
911     struct ble_ll_conn_sm *connsm;
912 
913     connsm = (struct ble_ll_conn_sm *)arg;
914     CONN_F_ENCRYPTED(connsm) = 0;
915     ble_ll_conn_current_sm_over(connsm);
916 }
917 
918 static void
ble_ll_conn_continue_rx_encrypt(void * arg)919 ble_ll_conn_continue_rx_encrypt(void *arg)
920 {
921     struct ble_ll_conn_sm *connsm;
922 
923     connsm = (struct ble_ll_conn_sm *)arg;
924     ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.rx_pkt_cntr,
925                                  !CONN_IS_MASTER(connsm));
926 }
927 #endif
928 
929 /**
930  * Returns the cputime of the next scheduled item on the scheduler list or
931  * when the current connection will start its next interval (whichever is
932  * earlier). This API is called when determining at what time we should end
933  * the current connection event. The current connection event must end before
934  * the next scheduled item. However, the current connection itself is not
935  * in the scheduler list! Thus, we need to calculate the time at which the
936  * next connection will start (the schedule start time; not the anchor point)
937  * and not overrun it.
938  *
939  * Context: Interrupt
940  *
941  * @param connsm
942  *
943  * @return uint32_t
944  */
945 static uint32_t
ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm * connsm)946 ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm)
947 {
948 #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
949     uint32_t ce_end;
950     ce_end = connsm->ce_end_time;
951 #else
952     uint32_t ce_end;
953     uint32_t next_sched_time;
954 
955     /* Calculate time at which next connection event will start */
956     /* NOTE: We dont care if this time is tick short. */
957     ce_end = connsm->anchor_point + connsm->conn_itvl_ticks -
958         g_ble_ll_sched_offset_ticks;
959     if ((connsm->anchor_point_usecs + connsm->conn_itvl_usecs) >= 31) {
960         ++ce_end;
961     }
962 
963     if (ble_ll_sched_next_time(&next_sched_time)) {
964         if (CPUTIME_LT(next_sched_time, ce_end)) {
965             ce_end = next_sched_time;
966         }
967     }
968 #endif
969 
970     return ce_end;
971 }
972 
973 /**
974  * Called to check if certain connection state machine flags have been
975  * set.
976  *
977  * @param connsm
978  */
979 static void
ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm * connsm)980 ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm)
981 {
982     uint8_t update_status;
983 
984 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
985     if (connsm->csmflags.cfbit.send_ltk_req) {
986         /*
987          * Send Long term key request event to host. If masked, we need to
988          * send a REJECT_IND.
989          */
990         if (ble_ll_hci_ev_ltk_req(connsm)) {
991             ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ,
992                                         BLE_ERR_PINKEY_MISSING);
993         }
994         connsm->csmflags.cfbit.send_ltk_req = 0;
995     }
996 #endif
997 
998     /*
999      * There are two cases where this flag gets set:
1000      * 1) A connection update procedure was started and the event counter
1001      * has passed the instant.
1002      * 2) We successfully sent the reject reason.
1003      */
1004     if (connsm->csmflags.cfbit.host_expects_upd_event) {
1005         update_status = BLE_ERR_SUCCESS;
1006         if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE)) {
1007             ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE);
1008         } else {
1009             if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) {
1010                 ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ);
1011                 update_status = connsm->reject_reason;
1012             }
1013         }
1014         ble_ll_hci_ev_conn_update(connsm, update_status);
1015         connsm->csmflags.cfbit.host_expects_upd_event = 0;
1016     }
1017 
1018     /* Check if we need to send PHY update complete event */
1019 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1020     if (CONN_F_PHY_UPDATE_EVENT(connsm)) {
1021         if (!ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS)) {
1022             /* Sent event. Clear flag */
1023             CONN_F_PHY_UPDATE_EVENT(connsm) = 0;
1024         }
1025     }
1026 #endif
1027 }
1028 
1029 /**
1030  * Called when we want to send a data channel pdu inside a connection event.
1031  *
1032  * Context: interrupt
1033  *
1034  * @param connsm
1035  *
1036  * @return int 0: success; otherwise failure to transmit
1037  */
1038 static uint16_t
ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm * connsm,uint16_t pyld_len)1039 ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len)
1040 {
1041     uint16_t phy_max_tx_octets;
1042     uint16_t ret;
1043 
1044 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1045     uint8_t phy_mode;
1046 
1047     if (connsm->phy_tx_transition != BLE_PHY_TRANSITION_INVALID) {
1048         phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_tx_transition,
1049                                           connsm->phy_data.phy_options);
1050     } else {
1051         phy_mode = connsm->phy_data.tx_phy_mode;
1052     }
1053 
1054     phy_max_tx_octets = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time,
1055                                                      phy_mode);
1056 
1057 #else
1058     phy_max_tx_octets = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time,
1059                                                      BLE_PHY_MODE_1M);
1060 #endif
1061 
1062     ret = pyld_len;
1063 
1064     if (ret > connsm->eff_max_tx_octets) {
1065         ret = connsm->eff_max_tx_octets;
1066     }
1067 
1068     if (ret > phy_max_tx_octets) {
1069         ret = phy_max_tx_octets;
1070     }
1071 
1072     return ret;
1073 }
1074 
1075 static int
ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm * connsm)1076 ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm)
1077 {
1078     int rc;
1079     uint8_t md;
1080     uint8_t hdr_byte;
1081     uint8_t end_transition;
1082     uint8_t cur_txlen;
1083     uint8_t next_txlen;
1084     uint8_t cur_offset;
1085     uint16_t pktlen;
1086     uint32_t next_event_time;
1087     uint32_t ticks;
1088     struct os_mbuf *m;
1089     struct ble_mbuf_hdr *ble_hdr;
1090     struct os_mbuf_pkthdr *pkthdr;
1091     struct os_mbuf_pkthdr *nextpkthdr;
1092     struct ble_ll_empty_pdu empty_pdu;
1093     ble_phy_tx_end_func txend_func;
1094     int tx_phy_mode;
1095 
1096     /* For compiler warnings... */
1097     ble_hdr = NULL;
1098     m = NULL;
1099     md = 0;
1100     hdr_byte = BLE_LL_LLID_DATA_FRAG;
1101 
1102     /*
1103      * We need to check if we are retrying a pdu or if there is a pdu on
1104      * the transmit queue.
1105      */
1106     pkthdr = STAILQ_FIRST(&connsm->conn_txq);
1107     if (!connsm->cur_tx_pdu && !CONN_F_EMPTY_PDU_TXD(connsm) && !pkthdr) {
1108         CONN_F_EMPTY_PDU_TXD(connsm) = 1;
1109         goto conn_tx_pdu;
1110     }
1111 
1112     /*
1113      * If we dont have a pdu we have previously transmitted, take it off
1114      * the connection transmit queue
1115      */
1116     cur_offset = 0;
1117     if (!connsm->cur_tx_pdu && !CONN_F_EMPTY_PDU_TXD(connsm)) {
1118         /* Convert packet header to mbuf */
1119         m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
1120         nextpkthdr = STAILQ_NEXT(pkthdr, omp_next);
1121 
1122 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1123         /*
1124          * If we are encrypting, we are only allowed to send certain
1125          * kinds of LL control PDU's. If none is enqueued, send empty pdu!
1126          */
1127         if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
1128             if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) {
1129                 CONN_F_EMPTY_PDU_TXD(connsm) = 1;
1130                 goto conn_tx_pdu;
1131             }
1132 
1133             /*
1134              * We will allow a next packet if it itself is allowed or we are
1135              * a slave and we are sending the START_ENC_RSP. The master has
1136              * to wait to receive the START_ENC_RSP from the slave before
1137              * packets can be let go.
1138              */
1139             if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr)
1140                 && ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) ||
1141                     !ble_ll_ctrl_is_start_enc_rsp(m))) {
1142                 nextpkthdr = NULL;
1143             }
1144         }
1145 #endif
1146         /* Take packet off queue*/
1147         STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
1148         ble_hdr = BLE_MBUF_HDR_PTR(m);
1149 
1150         /*
1151          * We dequeued new packet for transmission so need to calculate payload
1152          * length we can send over current PHY. Effectively, this determines
1153          * fragmentation of packet into PDUs.
1154          */
1155         pktlen = pkthdr->omp_len;
1156         cur_txlen = ble_ll_conn_adjust_pyld_len(connsm, pktlen);
1157         ble_hdr->txinfo.pyld_len = cur_txlen;
1158 
1159         /* NOTE: header was set when first enqueued */
1160         hdr_byte = ble_hdr->txinfo.hdr_byte;
1161         connsm->cur_tx_pdu = m;
1162     } else {
1163         nextpkthdr = pkthdr;
1164         if (connsm->cur_tx_pdu) {
1165             m = connsm->cur_tx_pdu;
1166             ble_hdr = BLE_MBUF_HDR_PTR(m);
1167             pktlen = OS_MBUF_PKTLEN(m);
1168             cur_txlen = ble_hdr->txinfo.pyld_len;
1169             cur_offset = ble_hdr->txinfo.offset;
1170             if (cur_offset == 0) {
1171                 hdr_byte = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
1172             }
1173 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1174             if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
1175                 /* We will allow a next packet if it itself is allowed */
1176                 pkthdr = OS_MBUF_PKTHDR(connsm->cur_tx_pdu);
1177                 if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr)
1178                     && ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) ||
1179                         !ble_ll_ctrl_is_start_enc_rsp(connsm->cur_tx_pdu))) {
1180                     nextpkthdr = NULL;
1181                 }
1182             }
1183 #endif
1184         } else {
1185             /* Empty PDU here. NOTE: header byte gets set later */
1186             pktlen = 0;
1187             cur_txlen = 0;
1188 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1189             if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
1190                 /* We will allow a next packet if it itself is allowed */
1191                 if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr)) {
1192                     nextpkthdr = NULL;
1193                 }
1194             }
1195 #endif
1196         }
1197     }
1198 
1199     /*
1200      * Set the more data data flag if we have more data to send and we
1201      * have not been asked to terminate
1202      */
1203     if ((nextpkthdr || ((cur_offset + cur_txlen) < pktlen)) &&
1204          !connsm->csmflags.cfbit.terminate_ind_rxd) {
1205         /* Get next event time */
1206         next_event_time = ble_ll_conn_get_next_sched_time(connsm);
1207 
1208         /* XXX: TODO: need to check this with phy update procedure. There are
1209            limitations if we have started update */
1210 
1211         /*
1212          * Dont bother to set the MD bit if we cannot do the following:
1213          *  -> wait IFS, send the current frame.
1214          *  -> wait IFS, receive a maximum size frame.
1215          *  -> wait IFS, send the next frame.
1216          *  -> wait IFS, receive a maximum size frame.
1217          *
1218          *  For slave:
1219          *  -> wait IFS, send current frame.
1220          *  -> wait IFS, receive maximum size frame.
1221          *  -> wait IFS, send next frame.
1222          */
1223         if ((cur_offset + cur_txlen) < pktlen) {
1224             next_txlen = pktlen - (cur_offset + cur_txlen);
1225         } else {
1226             if (nextpkthdr->omp_len > connsm->eff_max_tx_octets) {
1227                 next_txlen = connsm->eff_max_tx_octets;
1228             } else {
1229                 next_txlen = nextpkthdr->omp_len;
1230             }
1231         }
1232 
1233         /*
1234          * XXX: this calculation is based on using the current time
1235          * and assuming the transmission will occur an IFS time from
1236          * now. This is not the most accurate especially if we have
1237          * received a frame and we are replying to it.
1238          */
1239 #if BLE_LL_BT5_PHY_SUPPORTED
1240         tx_phy_mode = connsm->phy_data.tx_phy_mode;
1241 #else
1242         tx_phy_mode = BLE_PHY_MODE_1M;
1243 #endif
1244 
1245         ticks = (BLE_LL_IFS * 3) + connsm->eff_max_rx_time +
1246             ble_ll_pdu_tx_time_get(next_txlen, tx_phy_mode) +
1247             ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode);
1248 
1249         if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
1250             ticks += (BLE_LL_IFS + connsm->eff_max_rx_time);
1251         }
1252 
1253         ticks = os_cputime_usecs_to_ticks(ticks);
1254         if ((int32_t)((os_cputime_get32() + ticks) - next_event_time) < 0) {
1255             md = 1;
1256         }
1257      }
1258 
1259     /* If we send an empty PDU we need to initialize the header */
1260 conn_tx_pdu:
1261     if (CONN_F_EMPTY_PDU_TXD(connsm)) {
1262         /*
1263          * This looks strange, but we dont use the data pointer in the mbuf
1264          * when we have an empty pdu.
1265          */
1266         m = (struct os_mbuf *)&empty_pdu;
1267         m->om_data = (uint8_t *)&empty_pdu;
1268         m->om_data += BLE_MBUF_MEMBLOCK_OVERHEAD;
1269         ble_hdr = &empty_pdu.ble_hdr;
1270         ble_hdr->txinfo.flags = 0;
1271         ble_hdr->txinfo.offset = 0;
1272         ble_hdr->txinfo.pyld_len = 0;
1273     }
1274 
1275     /* Set tx seqnum */
1276     if (connsm->tx_seqnum) {
1277         hdr_byte |= BLE_LL_DATA_HDR_SN_MASK;
1278     }
1279 
1280     /* If we have more data, set the bit */
1281     if (md) {
1282         hdr_byte |= BLE_LL_DATA_HDR_MD_MASK;
1283     }
1284 
1285     /* Set NESN (next expected sequence number) bit */
1286     if (connsm->next_exp_seqnum) {
1287         hdr_byte |= BLE_LL_DATA_HDR_NESN_MASK;
1288     }
1289 
1290     /* Set the header byte in the outgoing frame */
1291     ble_hdr->txinfo.hdr_byte = hdr_byte;
1292 
1293     /*
1294      * If we are a slave, check to see if this transmission will end the
1295      * connection event. We will end the connection event if we have
1296      * received a valid frame with the more data bit set to 0 and we dont
1297      * have more data.
1298      *
1299      * XXX: for a slave, we dont check to see if we can:
1300      *  -> wait IFS, rx frame from master (either big or small).
1301      *  -> wait IFS, send empty pdu or next pdu.
1302      *
1303      *  We could do this. Now, we just keep going and hope that we dont
1304      *  overrun next scheduled item.
1305      */
1306     if ((connsm->csmflags.cfbit.terminate_ind_rxd) ||
1307         ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && (md == 0) &&
1308          (connsm->cons_rxd_bad_crc == 0) &&
1309          ((connsm->last_rxd_hdr_byte & BLE_LL_DATA_HDR_MD_MASK) == 0) &&
1310          !ble_ll_ctrl_is_terminate_ind(hdr_byte, m->om_data[0]))) {
1311         /* We will end the connection event */
1312         end_transition = BLE_PHY_TRANSITION_NONE;
1313         txend_func = ble_ll_conn_wait_txend;
1314     } else {
1315         /* Wait for a response here */
1316         end_transition = BLE_PHY_TRANSITION_TX_RX;
1317         txend_func = NULL;
1318     }
1319 
1320 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1321     int is_ctrl;
1322     uint8_t llid;
1323     uint8_t opcode;
1324 
1325     llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
1326     if (llid == BLE_LL_LLID_CTRL) {
1327         is_ctrl = 1;
1328         opcode = m->om_data[0];
1329     } else {
1330         is_ctrl = 0;
1331         opcode = 0;
1332     }
1333 
1334     if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_RSP)) {
1335         /*
1336          * Both master and slave send the START_ENC_RSP encrypted and receive
1337          * encrypted
1338          */
1339         CONN_F_ENCRYPTED(connsm) = 1;
1340         connsm->enc_data.tx_encrypted = 1;
1341         ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
1342                                connsm->enc_data.iv,
1343                                connsm->enc_data.enc_block.cipher_text,
1344                                CONN_IS_MASTER(connsm));
1345     } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) {
1346         /*
1347          * Only the slave sends this and it gets sent unencrypted but
1348          * we receive encrypted
1349          */
1350         CONN_F_ENCRYPTED(connsm) = 0;
1351         connsm->enc_data.enc_state = CONN_ENC_S_START_ENC_RSP_WAIT;
1352         connsm->enc_data.tx_encrypted = 0;
1353         ble_phy_encrypt_disable();
1354         if (txend_func == NULL) {
1355             txend_func = ble_ll_conn_start_rx_encrypt;
1356         } else {
1357             txend_func = ble_ll_conn_txend_encrypt;
1358         }
1359     } else if (is_ctrl && (opcode == BLE_LL_CTRL_PAUSE_ENC_RSP)) {
1360         /*
1361          * The slave sends the PAUSE_ENC_RSP encrypted. The master sends
1362          * it unencrypted (note that link was already set unencrypted).
1363          */
1364         if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
1365             CONN_F_ENCRYPTED(connsm) = 1;
1366             connsm->enc_data.tx_encrypted = 1;
1367             ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
1368                                    connsm->enc_data.iv,
1369                                    connsm->enc_data.enc_block.cipher_text,
1370                                    CONN_IS_MASTER(connsm));
1371             if (txend_func == NULL) {
1372                 txend_func = ble_ll_conn_start_rx_unencrypt;
1373             } else {
1374                 txend_func = ble_ll_conn_rxend_unencrypt;
1375             }
1376         } else {
1377             CONN_F_ENCRYPTED(connsm) = 0;
1378             connsm->enc_data.enc_state = CONN_ENC_S_PAUSED;
1379             connsm->enc_data.tx_encrypted = 0;
1380             ble_phy_encrypt_disable();
1381         }
1382     } else {
1383         /* If encrypted set packet counter */
1384         if (CONN_F_ENCRYPTED(connsm)) {
1385             connsm->enc_data.tx_encrypted = 1;
1386             ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.tx_pkt_cntr,
1387                                          CONN_IS_MASTER(connsm));
1388             if (txend_func == NULL) {
1389                 txend_func = ble_ll_conn_continue_rx_encrypt;
1390             }
1391         }
1392     }
1393 #endif
1394 
1395 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1396     ble_phy_mode_set(connsm->phy_data.tx_phy_mode,connsm->phy_data.rx_phy_mode);
1397 #endif
1398 
1399     /* Set transmit end callback */
1400     ble_phy_set_txend_cb(txend_func, connsm);
1401     rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, m, end_transition);
1402     if (!rc) {
1403         /* Log transmit on connection state */
1404         cur_txlen = ble_hdr->txinfo.pyld_len;
1405         ble_ll_trace_u32x2(BLE_LL_TRACE_ID_CONN_TX, cur_txlen,
1406                            ble_hdr->txinfo.offset);
1407 
1408         /* Set last transmitted MD bit */
1409         CONN_F_LAST_TXD_MD(connsm) = md;
1410 
1411         /* Increment packets transmitted */
1412         if (CONN_F_EMPTY_PDU_TXD(connsm)) {
1413             STATS_INC(ble_ll_conn_stats, tx_empty_pdus);
1414         } else if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
1415             STATS_INC(ble_ll_conn_stats, tx_ctrl_pdus);
1416             STATS_INCN(ble_ll_conn_stats, tx_ctrl_bytes, cur_txlen);
1417         } else {
1418             STATS_INC(ble_ll_conn_stats, tx_l2cap_pdus);
1419             STATS_INCN(ble_ll_conn_stats, tx_l2cap_bytes, cur_txlen);
1420         }
1421     }
1422     return rc;
1423 }
1424 
1425 /**
1426  * Schedule callback for start of connection event.
1427  *
1428  * Context: Interrupt
1429  *
1430  * @param sch
1431  *
1432  * @return int 0: scheduled item is still running. 1: schedule item is done.
1433  */
1434 static int
ble_ll_conn_event_start_cb(struct ble_ll_sched_item * sch)1435 ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
1436 {
1437     int rc;
1438     uint32_t usecs;
1439     uint32_t start;
1440     struct ble_ll_conn_sm *connsm;
1441 
1442     /* XXX: note that we can extend end time here if we want. Look at this */
1443 
1444     /* Set current connection state machine */
1445     connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
1446     g_ble_ll_conn_cur_sm = connsm;
1447     BLE_LL_ASSERT(connsm);
1448 
1449     /* Log connection event start */
1450     ble_ll_trace_u32(BLE_LL_TRACE_ID_CONN_EV_START, connsm->conn_handle);
1451 
1452     /* Disable whitelisting as connections do not use it */
1453     ble_ll_whitelist_disable();
1454 
1455     /* Set LL state */
1456     ble_ll_state_set(BLE_LL_STATE_CONNECTION);
1457 
1458     /* Set channel */
1459     ble_phy_setchan(connsm->data_chan_index, connsm->access_addr,
1460                     connsm->crcinit);
1461 
1462 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
1463     ble_phy_resolv_list_disable();
1464 #endif
1465 
1466     if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
1467         /* Set start time of transmission */
1468         start = sch->start_time + g_ble_ll_sched_offset_ticks;
1469         rc = ble_phy_tx_set_start_time(start, sch->remainder);
1470         if (!rc) {
1471 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1472             if (CONN_F_ENCRYPTED(connsm)) {
1473                 ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr,
1474                                        connsm->enc_data.iv,
1475                                        connsm->enc_data.enc_block.cipher_text,
1476                                        1);
1477             } else {
1478                 ble_phy_encrypt_disable();
1479             }
1480 #endif
1481             rc = ble_ll_conn_tx_data_pdu(connsm);
1482             if (!rc) {
1483                 rc = BLE_LL_SCHED_STATE_RUNNING;
1484             } else {
1485                 /* Inform LL task of connection event end */
1486                 rc = BLE_LL_SCHED_STATE_DONE;
1487             }
1488         } else {
1489             STATS_INC(ble_ll_conn_stats, conn_ev_late);
1490             rc = BLE_LL_SCHED_STATE_DONE;
1491         }
1492     } else {
1493 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
1494         if (CONN_F_ENCRYPTED(connsm)) {
1495             ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr,
1496                                    connsm->enc_data.iv,
1497                                    connsm->enc_data.enc_block.cipher_text,
1498                                    1);
1499         } else {
1500             ble_phy_encrypt_disable();
1501         }
1502 #endif
1503 
1504 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1505         ble_phy_mode_set(connsm->phy_data.rx_phy_mode,
1506                              connsm->phy_data.rx_phy_mode);
1507 #endif
1508 
1509         /* XXX: what is this really for the slave? */
1510         start = sch->start_time + g_ble_ll_sched_offset_ticks;
1511         rc = ble_phy_rx_set_start_time(start, sch->remainder);
1512         if (rc) {
1513             /* End the connection event as we have no more buffers */
1514             STATS_INC(ble_ll_conn_stats, slave_ce_failures);
1515             rc = BLE_LL_SCHED_STATE_DONE;
1516         } else {
1517             /*
1518              * Set flag that tells slave to set last anchor point if a packet
1519              * has been received.
1520              */
1521             connsm->csmflags.cfbit.slave_set_last_anchor = 1;
1522 
1523             /*
1524              * Set the wait for response time. The anchor point is when we
1525              * expect the master to start transmitting. Worst-case, we expect
1526              * to hear a reply within the anchor point plus:
1527              *  -> current tx window size
1528              *  -> current window widening amount (includes +/- 16 usec jitter)
1529              *  -> Amount of time it takes to detect packet start.
1530              *  -> Some extra time (16 usec) to insure timing is OK
1531              */
1532 
1533             /*
1534              * For the 32 kHz crystal, the amount of usecs we have to wait
1535              * is not from the anchor point; we have to account for the time
1536              * from when the receiver is enabled until the anchor point. The
1537              * time we start before the anchor point is this:
1538              *   -> current window widening.
1539              *   -> up to one 32 kHz tick since we discard remainder.
1540              *   -> Up to one tick since the usecs to ticks calc can be off
1541              *   by up to one tick.
1542              * NOTES:
1543              * 1) the 61 we add is for the two ticks mentioned above.
1544              * 2) The address rx time and jitter is accounted for in the
1545              * phy function
1546              */
1547             usecs = connsm->slave_cur_tx_win_usecs + 61 +
1548                 (2 * connsm->slave_cur_window_widening);
1549             ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, usecs);
1550             /* Set next wakeup time to connection event end time */
1551             rc = BLE_LL_SCHED_STATE_RUNNING;
1552         }
1553     }
1554 
1555     if (rc == BLE_LL_SCHED_STATE_DONE) {
1556         ble_ll_event_send(&connsm->conn_ev_end);
1557         ble_phy_disable();
1558         ble_ll_state_set(BLE_LL_STATE_STANDBY);
1559         g_ble_ll_conn_cur_sm = NULL;
1560     }
1561 
1562     /* Set time that we last serviced the schedule */
1563     connsm->last_scheduled = os_cputime_get32();
1564     return rc;
1565 }
1566 
1567 /**
1568  * Called to determine if the device is allowed to send the next pdu in the
1569  * connection event. This will always return 'true' if we are a slave. If we
1570  * are a master, we must be able to send the next fragment and get a minimum
1571  * sized response from the slave.
1572  *
1573  * Context: Interrupt context (rx end isr).
1574  *
1575  * @param connsm
1576  * @param begtime   Time at which IFS before pdu transmission starts
1577  *
1578  * @return int 0: not allowed to send 1: allowed to send
1579  */
1580 static int
ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm * connsm,uint32_t begtime,uint32_t add_usecs)1581 ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime,
1582                               uint32_t add_usecs)
1583 {
1584     int rc;
1585     uint8_t rem_bytes;
1586     uint32_t ticks;
1587     uint32_t usecs;
1588     uint32_t next_sched_time;
1589     struct os_mbuf *txpdu;
1590     struct os_mbuf_pkthdr *pkthdr;
1591     struct ble_mbuf_hdr *txhdr;
1592     uint32_t allowed_usecs;
1593     int tx_phy_mode;
1594 
1595 #if BLE_LL_BT5_PHY_SUPPORTED
1596     tx_phy_mode = connsm->phy_data.tx_phy_mode;
1597 #else
1598     tx_phy_mode = BLE_PHY_MODE_1M;
1599 #endif
1600 
1601     rc = 1;
1602     if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
1603         /* Get next scheduled item time */
1604         next_sched_time = ble_ll_conn_get_next_sched_time(connsm);
1605 
1606         txpdu = connsm->cur_tx_pdu;
1607         if (!txpdu) {
1608             pkthdr = STAILQ_FIRST(&connsm->conn_txq);
1609             if (pkthdr) {
1610                 txpdu = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
1611             }
1612         } else {
1613             pkthdr = OS_MBUF_PKTHDR(txpdu);
1614         }
1615 
1616         /* XXX: TODO: need to check this with phy update procedure. There are
1617            limitations if we have started update */
1618         if (txpdu) {
1619             txhdr = BLE_MBUF_HDR_PTR(txpdu);
1620             rem_bytes = pkthdr->omp_len - txhdr->txinfo.offset;
1621             if (rem_bytes > connsm->eff_max_tx_octets) {
1622                 rem_bytes = connsm->eff_max_tx_octets;
1623             }
1624             usecs = ble_ll_pdu_tx_time_get(rem_bytes, tx_phy_mode);
1625         } else {
1626             /* We will send empty pdu (just a LL header) */
1627             usecs = ble_ll_pdu_tx_time_get(0, tx_phy_mode);
1628         }
1629         usecs += (BLE_LL_IFS * 2) + connsm->eff_max_rx_time;
1630 
1631         ticks = (uint32_t)(next_sched_time - begtime);
1632         allowed_usecs = os_cputime_ticks_to_usecs(ticks);
1633         if ((usecs + add_usecs) >= allowed_usecs) {
1634             rc = 0;
1635         }
1636     }
1637 
1638     return rc;
1639 }
1640 
1641 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
1642 /**
1643  * Callback for the Authenticated payload timer. This function is called
1644  * when the authenticated payload timer expires. When the authenticated
1645  * payload timeout expires, we should
1646  *  -> Send the authenticated payload timeout event.
1647  *  -> Start the LE ping procedure.
1648  *  -> Restart the timer.
1649  *
1650  * @param arg
1651  */
1652 void
ble_ll_conn_auth_pyld_timer_cb(struct ble_npl_event * ev)1653 ble_ll_conn_auth_pyld_timer_cb(struct ble_npl_event *ev)
1654 {
1655     struct ble_ll_conn_sm *connsm;
1656 
1657     connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev);
1658     ble_ll_auth_pyld_tmo_event_send(connsm);
1659     ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING);
1660     ble_ll_conn_auth_pyld_timer_start(connsm);
1661 }
1662 
1663 void
ble_ll_conn_rd_features_timer_cb(struct ble_npl_event * ev)1664 ble_ll_conn_rd_features_timer_cb(struct ble_npl_event *ev)
1665 {
1666     struct ble_ll_conn_sm *connsm;
1667 
1668     connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev);
1669 
1670     if (!connsm->csmflags.cfbit.pending_hci_rd_features ||
1671                                         !connsm->csmflags.cfbit.rxd_features) {
1672         return;
1673     }
1674 
1675     ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS);
1676     connsm->csmflags.cfbit.pending_hci_rd_features = 0;
1677 }
1678 
1679 /**
1680  * Start (or restart) the authenticated payload timer
1681  *
1682  * @param connsm
1683  */
1684 void
ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm * connsm)1685 ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm)
1686 {
1687     int32_t tmo;
1688 
1689     /* Timeout in is in 10 msec units */
1690     tmo = (int32_t)BLE_LL_CONN_AUTH_PYLD_OS_TMO(connsm->auth_pyld_tmo);
1691     ble_npl_callout_reset(&connsm->auth_pyld_timer, tmo);
1692 }
1693 #endif
1694 
1695 static void
ble_ll_conn_master_common_init(struct ble_ll_conn_sm * connsm)1696 ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm)
1697 {
1698 
1699     /* Set master role */
1700     connsm->conn_role = BLE_LL_CONN_ROLE_MASTER;
1701 
1702     /* Set default ce parameters */
1703 
1704     /*
1705      * XXX: for now, we need twice the transmit window as our calculations
1706      * for the transmit window offset could be off.
1707      */
1708     connsm->tx_win_size = BLE_LL_CONN_TX_WIN_MIN + 1;
1709     connsm->tx_win_off = 0;
1710     connsm->master_sca = MYNEWT_VAL(BLE_LL_MASTER_SCA);
1711 
1712     /* Hop increment is a random value between 5 and 16. */
1713     connsm->hop_inc = (rand() % 12) + 5;
1714 
1715     /* Set channel map to map requested by host */
1716     connsm->num_used_chans = g_ble_ll_conn_params.num_used_chans;
1717     memcpy(connsm->chanmap, g_ble_ll_conn_params.master_chan_map,
1718            BLE_LL_CONN_CHMAP_LEN);
1719 
1720     /*  Calculate random access address and crc initialization value */
1721     connsm->access_addr = ble_ll_conn_calc_access_addr();
1722     connsm->crcinit = rand() & 0xffffff;
1723 
1724     /* Set initial schedule callback */
1725     connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
1726 }
1727 /**
1728  * Called when a create connection command has been received. This initializes
1729  * a connection state machine in the master role.
1730  *
1731  * NOTE: Must be called before the state machine is started
1732  *
1733  * @param connsm
1734  * @param hcc
1735  */
1736 void
ble_ll_conn_master_init(struct ble_ll_conn_sm * connsm,struct hci_create_conn * hcc)1737 ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm,
1738                         struct hci_create_conn *hcc)
1739 {
1740 
1741     ble_ll_conn_master_common_init(connsm);
1742 
1743     /* Set slave latency and supervision timeout */
1744     connsm->slave_latency = hcc->conn_latency;
1745     connsm->supervision_tmo = hcc->supervision_timeout;
1746 
1747     /* Set own address type and peer address if needed */
1748     connsm->own_addr_type = hcc->own_addr_type;
1749     if (hcc->filter_policy == 0) {
1750         memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN);
1751         connsm->peer_addr_type = hcc->peer_addr_type;
1752     }
1753 
1754     /* XXX: for now, just make connection interval equal to max */
1755     connsm->conn_itvl = hcc->conn_itvl_max;
1756 
1757     /* Check the min/max CE lengths are less than connection interval */
1758     if (hcc->min_ce_len > (connsm->conn_itvl * 2)) {
1759         connsm->min_ce_len = connsm->conn_itvl * 2;
1760     } else {
1761         connsm->min_ce_len = hcc->min_ce_len;
1762     }
1763 
1764     if (hcc->max_ce_len > (connsm->conn_itvl * 2)) {
1765         connsm->max_ce_len = connsm->conn_itvl * 2;
1766     } else {
1767         connsm->max_ce_len = hcc->max_ce_len;
1768     }
1769 }
1770 
1771 static void
ble_ll_update_max_tx_octets_phy_mode(struct ble_ll_conn_sm * connsm)1772 ble_ll_update_max_tx_octets_phy_mode(struct ble_ll_conn_sm *connsm)
1773 {
1774     uint32_t usecs;
1775 
1776     usecs = connsm->eff_max_tx_time;
1777 
1778     connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_1M] =
1779             ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_1M);
1780     connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_2M] =
1781             ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_2M);
1782     connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_CODED_125KBPS] =
1783             ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_CODED_125KBPS);
1784     connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_CODED_500KBPS] =
1785             ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_CODED_500KBPS);
1786 }
1787 
1788 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1789 
1790 static void
ble_ll_conn_set_phy(struct ble_ll_conn_sm * connsm,int tx_phy,int rx_phy)1791 ble_ll_conn_set_phy(struct ble_ll_conn_sm *connsm, int tx_phy, int rx_phy)
1792 {
1793 
1794     struct ble_ll_conn_phy_data *phy_data = &connsm->phy_data;
1795 
1796     phy_data->rx_phy_mode = ble_ll_phy_to_phy_mode(rx_phy,
1797                                                    BLE_HCI_LE_PHY_CODED_ANY);
1798     phy_data->cur_rx_phy = rx_phy;
1799 
1800     phy_data->tx_phy_mode = ble_ll_phy_to_phy_mode(tx_phy,
1801                                                    BLE_HCI_LE_PHY_CODED_ANY);
1802     phy_data->cur_tx_phy = tx_phy;
1803 
1804 }
1805 
1806 static void
ble_ll_conn_init_phy(struct ble_ll_conn_sm * connsm,int phy)1807 ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy)
1808 {
1809     struct ble_ll_conn_global_params *conngp;
1810 
1811     /* Always initialize symmetric PHY - controller can change this later */
1812     ble_ll_conn_set_phy(connsm, phy, phy);
1813 
1814     /* Update data length management to match initial PHY */
1815     conngp = &g_ble_ll_conn_params;
1816     connsm->max_tx_octets = conngp->conn_init_max_tx_octets;
1817     connsm->max_rx_octets = conngp->supp_max_rx_octets;
1818     if (phy == BLE_PHY_CODED) {
1819         connsm->max_tx_time = conngp->conn_init_max_tx_time_coded;
1820         connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED;
1821         connsm->rem_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN_CODED;
1822         connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN_CODED;
1823     } else {
1824         connsm->max_tx_time = conngp->conn_init_max_tx_time_uncoded;
1825         connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_UNCODED;
1826         connsm->rem_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN_UNCODED;
1827         connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN_UNCODED;
1828     }
1829     connsm->eff_max_tx_time = connsm->rem_max_tx_time;
1830     connsm->eff_max_rx_time = connsm->rem_max_rx_time;
1831     connsm->rem_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1832     connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1833     connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1834     connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1835 
1836     ble_ll_update_max_tx_octets_phy_mode(connsm);
1837 }
1838 
1839 #endif
1840 
1841 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
1842 
1843 void
ble_ll_conn_ext_master_init(struct ble_ll_conn_sm * connsm,struct hci_ext_create_conn * hcc)1844 ble_ll_conn_ext_master_init(struct ble_ll_conn_sm *connsm,
1845                         struct hci_ext_create_conn *hcc)
1846 {
1847 
1848     ble_ll_conn_master_common_init(connsm);
1849 
1850     /* Set own address type and peer address if needed */
1851     connsm->own_addr_type = hcc->own_addr_type;
1852     if (hcc->filter_policy == 0) {
1853         memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN);
1854         connsm->peer_addr_type = hcc->peer_addr_type;
1855     }
1856 
1857     connsm->initial_params = *hcc;
1858 }
1859 
1860 void
ble_ll_conn_ext_set_params(struct ble_ll_conn_sm * connsm,struct hci_ext_conn_params * hcc_params,int phy)1861 ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm,
1862                            struct hci_ext_conn_params *hcc_params, int phy)
1863 {
1864     /* Set slave latency and supervision timeout */
1865     connsm->slave_latency = hcc_params->conn_latency;
1866     connsm->supervision_tmo = hcc_params->supervision_timeout;
1867 
1868     /* XXX: for now, just make connection interval equal to max */
1869     connsm->conn_itvl = hcc_params->conn_itvl_max;
1870 
1871 
1872     /* Check the min/max CE lengths are less than connection interval */
1873     if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) {
1874         connsm->min_ce_len = connsm->conn_itvl * 2;
1875     } else {
1876         connsm->min_ce_len = hcc_params->min_ce_len;
1877     }
1878 
1879     if (hcc_params->max_ce_len > (connsm->conn_itvl * 2)) {
1880         connsm->max_ce_len = connsm->conn_itvl * 2;
1881     } else {
1882         connsm->max_ce_len = hcc_params->max_ce_len;
1883     }
1884 
1885     ble_ll_conn_calc_itvl_ticks(connsm);
1886 
1887 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1888     ble_ll_conn_init_phy(connsm, phy);
1889 #endif
1890 }
1891 
1892 
1893 #endif
1894 
1895 static void
ble_ll_conn_set_csa(struct ble_ll_conn_sm * connsm,bool chsel)1896 ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool chsel)
1897 {
1898 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
1899     if (chsel) {
1900         CONN_F_CSA2_SUPP(connsm) = 1;
1901         connsm->channel_id = ((connsm->access_addr & 0xffff0000) >> 16) ^
1902                               (connsm->access_addr & 0x0000ffff);
1903 
1904         /* calculate the next data channel */
1905         connsm->data_chan_index = ble_ll_conn_calc_dci(connsm, 0);
1906         return;
1907     }
1908 #endif
1909 
1910     connsm->last_unmapped_chan = 0;
1911 
1912     /* calculate the next data channel */
1913     connsm->data_chan_index = ble_ll_conn_calc_dci(connsm, 1);
1914 }
1915 
1916 /**
1917  * Create a new connection state machine. This is done once per
1918  * connection when the HCI command "create connection" is issued to the
1919  * controller or when a slave receives a connect request.
1920  *
1921  * Context: Link Layer task
1922  *
1923  * @param connsm
1924  */
1925 void
ble_ll_conn_sm_new(struct ble_ll_conn_sm * connsm)1926 ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
1927 {
1928     struct ble_ll_conn_global_params *conn_params;
1929 
1930     /* Reset following elements */
1931     connsm->csmflags.conn_flags = 0;
1932     connsm->event_cntr = 0;
1933     connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
1934     connsm->disconnect_reason = 0;
1935     connsm->conn_features = BLE_LL_CONN_INITIAL_FEATURES;
1936     memset(connsm->remote_features, 0, sizeof(connsm->remote_features));
1937     connsm->vers_nr = 0;
1938     connsm->comp_id = 0;
1939     connsm->sub_vers_nr = 0;
1940     connsm->reject_reason = BLE_ERR_SUCCESS;
1941     connsm->conn_rssi = BLE_LL_CONN_UNKNOWN_RSSI;
1942     connsm->rpa_index = -1;
1943 
1944     /* XXX: TODO set these based on PHY that started connection */
1945 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1946     connsm->phy_data.cur_tx_phy = BLE_PHY_1M;
1947     connsm->phy_data.cur_rx_phy = BLE_PHY_1M;
1948     connsm->phy_data.tx_phy_mode = BLE_PHY_MODE_1M;
1949     connsm->phy_data.rx_phy_mode = BLE_PHY_MODE_1M;
1950     connsm->phy_data.req_pref_tx_phys_mask = 0;
1951     connsm->phy_data.req_pref_rx_phys_mask = 0;
1952     connsm->phy_data.host_pref_tx_phys_mask = g_ble_ll_data.ll_pref_tx_phys;
1953     connsm->phy_data.host_pref_rx_phys_mask = g_ble_ll_data.ll_pref_rx_phys;
1954     connsm->phy_data.phy_options = 0;
1955     connsm->phy_tx_transition = BLE_PHY_TRANSITION_INVALID;
1956 #endif
1957 
1958     /* Reset current control procedure */
1959     connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE;
1960     connsm->pending_ctrl_procs = 0;
1961 
1962     /*
1963      * Set handle in connection update procedure to 0. If the handle
1964      * is non-zero it means that the host initiated the connection
1965      * parameter update request and the rest of the parameters are valid.
1966      */
1967     connsm->conn_param_req.handle = 0;
1968 
1969     /* Connection end event */
1970     ble_npl_event_init(&connsm->conn_ev_end, ble_ll_conn_event_end, connsm);
1971 
1972     /* Initialize transmit queue and ack/flow control elements */
1973     STAILQ_INIT(&connsm->conn_txq);
1974     connsm->cur_tx_pdu = NULL;
1975     connsm->tx_seqnum = 0;
1976     connsm->next_exp_seqnum = 0;
1977     connsm->cons_rxd_bad_crc = 0;
1978     connsm->last_rxd_sn = 1;
1979     connsm->completed_pkts = 0;
1980 
1981     /* initialize data length mgmt */
1982     conn_params = &g_ble_ll_conn_params;
1983     connsm->max_tx_octets = conn_params->conn_init_max_tx_octets;
1984     connsm->max_rx_octets = conn_params->supp_max_rx_octets;
1985     connsm->max_tx_time = conn_params->conn_init_max_tx_time;
1986     connsm->max_rx_time = conn_params->supp_max_rx_time;
1987     connsm->rem_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN;
1988     connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN;
1989     connsm->eff_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN;
1990     connsm->eff_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN;
1991     connsm->rem_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1992     connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1993     connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1994     connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
1995 
1996     ble_ll_update_max_tx_octets_phy_mode(connsm);
1997 
1998     /* Reset encryption data */
1999 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
2000     memset(&connsm->enc_data, 0, sizeof(struct ble_ll_conn_enc_data));
2001     connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED;
2002 #endif
2003 
2004 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
2005     connsm->auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO;
2006     CONN_F_LE_PING_SUPP(connsm) = 1;
2007     ble_npl_callout_init(&connsm->auth_pyld_timer,
2008                     &g_ble_ll_data.ll_evq,
2009                     ble_ll_conn_auth_pyld_timer_cb,
2010                     connsm);
2011 #endif
2012 
2013     ble_ll_conn_calc_itvl_ticks(connsm);
2014 
2015     /* Add to list of active connections */
2016     SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle);
2017 }
2018 
2019 /**
2020  * Called when a remotes data length parameters change.
2021  *
2022  * Context: Link Layer task
2023  *
2024  * @param connsm
2025  * @param req
2026  */
2027 void
ble_ll_conn_datalen_update(struct ble_ll_conn_sm * connsm,struct ble_ll_len_req * req)2028 ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm,
2029                            struct ble_ll_len_req *req)
2030 {
2031     int send_event;
2032     uint16_t eff_time;
2033     uint16_t eff_bytes;
2034 
2035     /* Update parameters */
2036     connsm->rem_max_rx_time = req->max_rx_time;
2037     connsm->rem_max_tx_time = req->max_tx_time;
2038     connsm->rem_max_rx_octets = req->max_rx_bytes;
2039     connsm->rem_max_tx_octets = req->max_tx_bytes;
2040 
2041     /* Assume no event sent */
2042     send_event = 0;
2043 
2044     /* See if effective times have changed */
2045     eff_time = min(connsm->rem_max_tx_time, connsm->max_rx_time);
2046     if (eff_time != connsm->eff_max_rx_time) {
2047         connsm->eff_max_rx_time = eff_time;
2048         send_event = 1;
2049     }
2050     eff_time = min(connsm->rem_max_rx_time, connsm->max_tx_time);
2051     if (eff_time != connsm->eff_max_tx_time) {
2052         connsm->eff_max_tx_time = eff_time;
2053         send_event = 1;
2054 
2055         ble_ll_update_max_tx_octets_phy_mode(connsm);
2056     }
2057     eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_rx_octets);
2058     if (eff_bytes != connsm->eff_max_rx_octets) {
2059         connsm->eff_max_rx_octets = eff_bytes;
2060         send_event = 1;
2061     }
2062     eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_tx_octets);
2063     if (eff_bytes != connsm->eff_max_tx_octets) {
2064         connsm->eff_max_tx_octets = eff_bytes;
2065         send_event = 1;
2066     }
2067 
2068     if (send_event) {
2069         ble_ll_hci_ev_datalen_chg(connsm);
2070     }
2071 }
2072 
2073 /**
2074  * Called when a connection is terminated
2075  *
2076  * Context: Link Layer task.
2077  *
2078  * @param connsm
2079  * @param ble_err
2080  */
2081 void
ble_ll_conn_end(struct ble_ll_conn_sm * connsm,uint8_t ble_err)2082 ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
2083 {
2084     struct os_mbuf *m;
2085     struct os_mbuf_pkthdr *pkthdr;
2086 #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
2087     os_sr_t sr;
2088 #endif
2089 
2090     /* Remove scheduler events just in case */
2091     ble_ll_sched_rmv_elem(&connsm->conn_sch);
2092 
2093     /* Stop any control procedures that might be running */
2094     ble_npl_callout_stop(&connsm->ctrl_proc_rsp_timer);
2095 
2096 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
2097     ble_npl_callout_stop(&connsm->auth_pyld_timer);
2098 #endif
2099 
2100     /* Remove from the active connection list */
2101     SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
2102 
2103     /* Free the current transmit pdu if there is one. */
2104     if (connsm->cur_tx_pdu) {
2105         os_mbuf_free_chain(connsm->cur_tx_pdu);
2106         connsm->cur_tx_pdu = NULL;
2107     }
2108 
2109     /* Free all packets on transmit queue */
2110     while (1) {
2111         /* Get mbuf pointer from packet header pointer */
2112         pkthdr = STAILQ_FIRST(&connsm->conn_txq);
2113         if (!pkthdr) {
2114             break;
2115         }
2116         STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
2117 
2118         m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
2119         os_mbuf_free_chain(m);
2120     }
2121 
2122     /* Make sure events off queue */
2123     ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end);
2124 
2125 #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
2126     /* Remove from occupied periods */
2127     OS_ENTER_CRITICAL(sr);
2128     BLE_LL_ASSERT(g_ble_ll_sched_data.sch_num_occ_periods > 0);
2129     BLE_LL_ASSERT(g_ble_ll_sched_data.sch_occ_period_mask & connsm->period_occ_mask);
2130     --g_ble_ll_sched_data.sch_num_occ_periods;
2131     g_ble_ll_sched_data.sch_occ_period_mask &= ~connsm->period_occ_mask;
2132     OS_EXIT_CRITICAL(sr);
2133 #endif
2134 
2135     /* Connection state machine is now idle */
2136     connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
2137 
2138     /*
2139      * If we have features and there's pending HCI command, send an event before
2140      * disconnection event so it does make sense to host.
2141      */
2142     if (connsm->csmflags.cfbit.pending_hci_rd_features &&
2143                                         connsm->csmflags.cfbit.rxd_features) {
2144         ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS);
2145         connsm->csmflags.cfbit.pending_hci_rd_features = 0;
2146     }
2147 
2148     /*
2149      * If there is still pending read features request HCI command, send an
2150      * event to complete it.
2151      */
2152     if (connsm->csmflags.cfbit.pending_hci_rd_features) {
2153         ble_ll_hci_ev_rd_rem_used_feat(connsm, ble_err);
2154         connsm->csmflags.cfbit.pending_hci_rd_features = 0;
2155     }
2156 
2157     /*
2158      * We need to send a disconnection complete event. Connection Complete for
2159      * canceling connection creation is sent from LE Create Connection Cancel
2160      * Command handler.
2161      *
2162      * If the ble error is "success" it means that the reset command was
2163      * received and we should not send an event.
2164      */
2165     if (ble_err && (ble_err != BLE_ERR_UNK_CONN_ID ||
2166                                 connsm->csmflags.cfbit.terminate_ind_rxd)) {
2167         ble_ll_disconn_comp_event_send(connsm, ble_err);
2168     }
2169 
2170     /* Put connection state machine back on free list */
2171     STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
2172 
2173     /* Log connection end */
2174     ble_ll_trace_u32x3(BLE_LL_TRACE_ID_CONN_END, connsm->conn_handle,
2175                        connsm->event_cntr, (uint32_t)ble_err);
2176 }
2177 
2178 /**
2179  * Called to move to the next connection event.
2180  *
2181  * Context: Link Layer task.
2182  *
2183  * @param connsm
2184  *
2185  * @return int
2186  */
2187 static int
ble_ll_conn_next_event(struct ble_ll_conn_sm * connsm)2188 ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
2189 {
2190     uint16_t latency;
2191     uint32_t itvl;
2192     uint32_t cur_ww;
2193     uint32_t max_ww;
2194     struct ble_ll_conn_upd_req *upd;
2195     uint32_t ticks;
2196     uint32_t usecs;
2197 
2198     /* XXX: deal with connection request procedure here as well */
2199     ble_ll_conn_chk_csm_flags(connsm);
2200 
2201     /* If unable to start terminate procedure, start it now */
2202     if (connsm->disconnect_reason && !CONN_F_TERMINATE_STARTED(connsm)) {
2203         ble_ll_ctrl_terminate_start(connsm);
2204     }
2205 
2206     if (CONN_F_TERMINATE_STARTED(connsm) && (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE)) {
2207         /* Some of the devices waits whole connection interval to ACK our
2208          * TERMINATE_IND sent as a Slave. Since we are here it means we are still waiting for ACK.
2209          * Make sure we catch it in next connection event.
2210          */
2211         connsm->slave_latency = 0;
2212     }
2213 
2214     /*
2215      * XXX: TODO Probably want to add checks to see if we need to start
2216      * a control procedure here as an instant may have prevented us from
2217      * starting one.
2218      */
2219 
2220     /*
2221      * XXX TODO: I think this is technically incorrect. We can allow slave
2222      * latency if we are doing one of these updates as long as we
2223      * know that the master has received the ACK to the PDU that set
2224      * the instant
2225      */
2226     /* Set event counter to the next connection event that we will tx/rx in */
2227     itvl = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
2228     latency = 1;
2229     if (connsm->csmflags.cfbit.allow_slave_latency      &&
2230         !connsm->csmflags.cfbit.conn_update_sched       &&
2231         !CONN_F_PHY_UPDATE_SCHED(connsm)                &&
2232         !connsm->csmflags.cfbit.chanmap_update_scheduled) {
2233         if (connsm->csmflags.cfbit.pkt_rxd) {
2234             latency += connsm->slave_latency;
2235             itvl = itvl * latency;
2236         }
2237     }
2238     connsm->event_cntr += latency;
2239 
2240     /* Set next connection event start time */
2241     /* We can use pre-calculated values for one interval if latency is 1. */
2242     if (latency == 1) {
2243         connsm->anchor_point += connsm->conn_itvl_ticks;
2244         connsm->anchor_point_usecs += connsm->conn_itvl_usecs;
2245     } else {
2246         uint32_t ticks;
2247         ticks = os_cputime_usecs_to_ticks(itvl);
2248         connsm->anchor_point += ticks;
2249         connsm->anchor_point_usecs += (itvl - os_cputime_ticks_to_usecs(ticks));
2250     }
2251     if (connsm->anchor_point_usecs >= 31) {
2252         ++connsm->anchor_point;
2253         connsm->anchor_point_usecs -= 31;
2254     }
2255 
2256     /*
2257      * If a connection update has been scheduled and the event counter
2258      * is now equal to the instant, we need to adjust the start of the
2259      * connection by the the transmit window offset. We also copy in the
2260      * update parameters as they now should take effect.
2261      */
2262     if (connsm->csmflags.cfbit.conn_update_sched &&
2263         (connsm->event_cntr == connsm->conn_update_req.instant)) {
2264 
2265         /* Set flag so we send connection update event */
2266         upd = &connsm->conn_update_req;
2267         if ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER)  ||
2268             ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) &&
2269              IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) ||
2270             (connsm->conn_itvl != upd->interval)            ||
2271             (connsm->slave_latency != upd->latency)         ||
2272             (connsm->supervision_tmo != upd->timeout)) {
2273             connsm->csmflags.cfbit.host_expects_upd_event = 1;
2274         }
2275 
2276         connsm->supervision_tmo = upd->timeout;
2277         connsm->slave_latency = upd->latency;
2278         connsm->tx_win_size = upd->winsize;
2279         connsm->slave_cur_tx_win_usecs =
2280             connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS;
2281         connsm->tx_win_off = upd->winoffset;
2282         connsm->conn_itvl = upd->interval;
2283         ble_ll_conn_calc_itvl_ticks(connsm);
2284         if (upd->winoffset != 0) {
2285             usecs = upd->winoffset * BLE_LL_CONN_ITVL_USECS;
2286             ticks = os_cputime_usecs_to_ticks(usecs);
2287             connsm->anchor_point += ticks;
2288             usecs = usecs - os_cputime_ticks_to_usecs(ticks);
2289             connsm->anchor_point_usecs += usecs;
2290             if (connsm->anchor_point_usecs >= 31) {
2291                 ++connsm->anchor_point;
2292                 connsm->anchor_point_usecs -= 31;
2293             }
2294         }
2295 
2296         /* Reset the starting point of the connection supervision timeout */
2297         connsm->last_rxd_pdu_cputime = connsm->anchor_point;
2298 
2299         /* Reset update scheduled flag */
2300         connsm->csmflags.cfbit.conn_update_sched = 0;
2301     }
2302 
2303     /*
2304      * If there is a channel map request pending and we have reached the
2305      * instant, change to new channel map. Note there is a special case here.
2306      * If we received a channel map update with an instant equal to the event
2307      * counter, when we get here the event counter has already been
2308      * incremented by 1. That is why we do a signed comparison and change to
2309      * new channel map once the event counter equals or has passed channel
2310      * map update instant.
2311      */
2312     if (connsm->csmflags.cfbit.chanmap_update_scheduled &&
2313         ((int16_t)(connsm->chanmap_instant - connsm->event_cntr) <= 0)) {
2314 
2315         /* XXX: there is a chance that the control packet is still on
2316          * the queue of the master. This means that we never successfully
2317          * transmitted update request. Would end up killing connection
2318            on slave side. Could ignore it or see if still enqueued. */
2319         connsm->num_used_chans =
2320             ble_ll_conn_calc_used_chans(connsm->req_chanmap);
2321         memcpy(connsm->chanmap, connsm->req_chanmap, BLE_LL_CONN_CHMAP_LEN);
2322 
2323         connsm->csmflags.cfbit.chanmap_update_scheduled = 0;
2324 
2325         ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD);
2326 
2327         /* XXX: host could have resent channel map command. Need to
2328            check to make sure we dont have to restart! */
2329     }
2330 
2331 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
2332     if (CONN_F_PHY_UPDATE_SCHED(connsm) &&
2333         (connsm->event_cntr == connsm->phy_instant)) {
2334 
2335         /* Set cur phy to new phy */
2336         if (connsm->phy_data.new_tx_phy) {
2337             connsm->phy_data.cur_tx_phy = connsm->phy_data.new_tx_phy;
2338             connsm->phy_data.tx_phy_mode =
2339                                 ble_ll_phy_to_phy_mode(connsm->phy_data.cur_tx_phy,
2340                                                    connsm->phy_data.phy_options);
2341         }
2342 
2343         if (connsm->phy_data.new_rx_phy) {
2344             connsm->phy_data.cur_rx_phy = connsm->phy_data.new_rx_phy;
2345             connsm->phy_data.rx_phy_mode =
2346                                 ble_ll_phy_to_phy_mode(connsm->phy_data.cur_rx_phy,
2347                                                    connsm->phy_data.phy_options);
2348         }
2349 
2350         /* Clear flags and set flag to send event at next instant */
2351         CONN_F_PHY_UPDATE_SCHED(connsm) = 0;
2352         CONN_F_PHY_UPDATE_EVENT(connsm) = 1;
2353 
2354         ble_ll_ctrl_phy_update_proc_complete(connsm);
2355     }
2356 #endif
2357 
2358     /* Calculate data channel index of next connection event */
2359     connsm->data_chan_index = ble_ll_conn_calc_dci(connsm, latency);
2360 
2361     /*
2362      * If we are trying to terminate connection, check if next wake time is
2363      * passed the termination timeout. If so, no need to continue with
2364      * connection as we will time out anyway.
2365      */
2366     if (CONN_F_TERMINATE_STARTED(connsm)) {
2367         if ((int32_t)(connsm->terminate_timeout - connsm->anchor_point) <= 0) {
2368             return -1;
2369         }
2370     }
2371 
2372     /*
2373      * Calculate ce end time. For a slave, we need to add window widening and
2374      * the transmit window if we still have one.
2375      */
2376 #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
2377     itvl = g_ble_ll_sched_data.sch_ticks_per_period;
2378 #else
2379     itvl = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT;
2380 #endif
2381     if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
2382         cur_ww = ble_ll_conn_calc_window_widening(connsm);
2383         max_ww = (connsm->conn_itvl * (BLE_LL_CONN_ITVL_USECS/2)) - BLE_LL_IFS;
2384         if (cur_ww >= max_ww) {
2385             return -1;
2386         }
2387         cur_ww += BLE_LL_JITTER_USECS;
2388         connsm->slave_cur_window_widening = cur_ww;
2389         itvl += os_cputime_usecs_to_ticks(cur_ww + connsm->slave_cur_tx_win_usecs);
2390     }
2391     itvl -= g_ble_ll_sched_offset_ticks;
2392     connsm->ce_end_time = connsm->anchor_point + itvl;
2393 
2394     return 0;
2395 }
2396 
2397 /**
2398  * Called when a connection has been created. This function will
2399  *  -> Set the connection state to created.
2400  *  -> Start the connection supervision timer
2401  *  -> Set the Link Layer state to connection.
2402  *  -> Send a connection complete event.
2403  *
2404  *  See Section 4.5.2 Vol 6 Part B
2405  *
2406  *  Context: Link Layer
2407  *
2408  * @param connsm
2409  *
2410  * @ return 0: connection NOT created. 1: connection created
2411  */
2412 static int
ble_ll_conn_created(struct ble_ll_conn_sm * connsm,struct ble_mbuf_hdr * rxhdr)2413 ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr)
2414 {
2415     int rc;
2416     uint8_t *evbuf;
2417     uint32_t endtime;
2418     uint32_t usecs;
2419 
2420     /* XXX: TODO this assumes we received in 1M phy */
2421 
2422     /* Set state to created */
2423     connsm->conn_state = BLE_LL_CONN_STATE_CREATED;
2424 
2425     /* Clear packet received flag */
2426     connsm->csmflags.cfbit.pkt_rxd = 0;
2427 
2428     /* Consider time created the last scheduled time */
2429     connsm->last_scheduled = os_cputime_get32();
2430 
2431     /*
2432      * Set the last rxd pdu time since this is where we want to start the
2433      * supervision timer from.
2434      */
2435     connsm->last_rxd_pdu_cputime = connsm->last_scheduled;
2436 
2437     /*
2438      * Set first connection event time. If slave the endtime is the receive end
2439      * time of the connect request. The actual connection starts 1.25 msecs plus
2440      * the transmit window offset from the end of the connection request.
2441      */
2442     rc = 1;
2443     if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
2444         /*
2445          * With a 32.768 kHz crystal we dont care about the remaining usecs
2446          * when setting last anchor point. The only thing last anchor is used
2447          * for is to calculate window widening. The effect of this is
2448          * negligible.
2449          */
2450         connsm->last_anchor_point = rxhdr->beg_cputime;
2451 
2452         usecs = rxhdr->rem_usecs + 1250 +
2453                 (connsm->tx_win_off * BLE_LL_CONN_TX_WIN_USECS) +
2454                 ble_ll_pdu_tx_time_get(BLE_CONNECT_REQ_LEN,
2455                                        rxhdr->rxinfo.phy_mode);
2456 
2457         if (rxhdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
2458             switch (rxhdr->rxinfo.phy) {
2459             case BLE_PHY_1M:
2460             case BLE_PHY_2M:
2461                 usecs += 1250;
2462                 break;
2463             case BLE_PHY_CODED:
2464                 usecs += 2500;
2465                 break;
2466             default:
2467                 BLE_LL_ASSERT(0);
2468                 break;
2469             }
2470         }
2471 
2472         /* Anchor point is cputime. */
2473         endtime = os_cputime_usecs_to_ticks(usecs);
2474         connsm->anchor_point = rxhdr->beg_cputime + endtime;
2475         connsm->anchor_point_usecs = usecs - os_cputime_ticks_to_usecs(endtime);
2476         if (connsm->anchor_point_usecs == 31) {
2477             ++connsm->anchor_point;
2478             connsm->anchor_point_usecs = 0;
2479         }
2480 
2481         connsm->slave_cur_tx_win_usecs =
2482             connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS;
2483 #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING)
2484         connsm->ce_end_time = connsm->anchor_point +
2485             g_ble_ll_sched_data.sch_ticks_per_period +
2486             os_cputime_usecs_to_ticks(connsm->slave_cur_tx_win_usecs) + 1;
2487 
2488 #else
2489         connsm->ce_end_time = connsm->anchor_point +
2490             (MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT)
2491             + os_cputime_usecs_to_ticks(connsm->slave_cur_tx_win_usecs) + 1;
2492 #endif
2493         connsm->slave_cur_window_widening = BLE_LL_JITTER_USECS;
2494 
2495         /* Start the scheduler for the first connection event */
2496         while (ble_ll_sched_slave_new(connsm)) {
2497             if (ble_ll_conn_next_event(connsm)) {
2498                 STATS_INC(ble_ll_conn_stats, cant_set_sched);
2499                 rc = 0;
2500                 break;
2501             }
2502         }
2503     }
2504 
2505     /* Send connection complete event to inform host of connection */
2506     if (rc) {
2507 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
2508         /*
2509          * If we have default phy preferences and they are different than
2510          * the current PHY's in use, start update procedure.
2511          */
2512         /*
2513          * XXX: should we attempt to start this without knowing if
2514          * the other side can support it?
2515          */
2516         if (!ble_ll_conn_chk_phy_upd_start(connsm)) {
2517             CONN_F_CTRLR_PHY_UPDATE(connsm) = 1;
2518         }
2519 #endif
2520         if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
2521             ble_ll_adv_send_conn_comp_ev(connsm, rxhdr);
2522         } else {
2523             evbuf = ble_ll_init_get_conn_comp_ev();
2524             ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, NULL);
2525 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
2526             ble_ll_hci_ev_le_csa(connsm);
2527 #endif
2528 
2529             /*
2530              * Initiate features exchange
2531              *
2532              * XXX we do this only as a master as it was observed that sending
2533              * LL_SLAVE_FEATURE_REQ after connection breaks some recent iPhone
2534              * models; for slave just assume master will initiate features xchg
2535              * if it has some additional features to use.
2536              */
2537             ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG);
2538         }
2539     }
2540 
2541     return rc;
2542 }
2543 
2544 /**
2545  * Called upon end of connection event
2546  *
2547  * Context: Link-layer task
2548  *
2549  * @param void *arg Pointer to connection state machine
2550  *
2551  */
2552 static void
ble_ll_conn_event_end(struct ble_npl_event * ev)2553 ble_ll_conn_event_end(struct ble_npl_event *ev)
2554 {
2555     uint8_t ble_err;
2556     uint32_t tmo;
2557     struct ble_ll_conn_sm *connsm;
2558 
2559     /* Better be a connection state machine! */
2560     connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev);
2561     BLE_LL_ASSERT(connsm);
2562 
2563     /* Log event end */
2564     ble_ll_trace_u32x2(BLE_LL_TRACE_ID_CONN_EV_END, connsm->conn_handle,
2565                        connsm->event_cntr);
2566 
2567     /* Check if we need to resume scanning */
2568     ble_ll_scan_chk_resume();
2569 
2570 #ifdef BLE_XCVR_RFCLK
2571     ble_ll_sched_rfclk_chk_restart();
2572 #endif
2573 
2574     /* If we have transmitted the terminate IND successfully, we are done */
2575     if ((connsm->csmflags.cfbit.terminate_ind_txd) ||
2576         (connsm->csmflags.cfbit.terminate_ind_rxd)) {
2577         if (connsm->csmflags.cfbit.terminate_ind_txd) {
2578             ble_err = BLE_ERR_CONN_TERM_LOCAL;
2579         } else {
2580             /* Make sure the disconnect reason is valid! */
2581             ble_err = connsm->rxd_disconnect_reason;
2582             if (ble_err == 0) {
2583                 ble_err = BLE_ERR_REM_USER_CONN_TERM;
2584             }
2585         }
2586         ble_ll_conn_end(connsm, ble_err);
2587         return;
2588     }
2589 
2590     /* Remove any connection end events that might be enqueued */
2591     ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end);
2592 
2593     /*
2594      * If we have received a packet, we can set the current transmit window
2595      * usecs to 0 since we dont need to listen in the transmit window.
2596      */
2597     if (connsm->csmflags.cfbit.pkt_rxd) {
2598         connsm->slave_cur_tx_win_usecs = 0;
2599     }
2600 
2601 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
2602     /*
2603      * If we are encrypted and have passed the authenticated payload timeout
2604      * we need to send an event to tell the host. Unfortunately, I think we
2605      * need one of these per connection and we have to set this timer
2606      * fairly accurately. So we need to another event in the connection.
2607      * This sucks.
2608      *
2609      * The way this works is that whenever the timer expires it just gets reset
2610      * and we send the autheticated payload timeout event. Note that this timer
2611      * should run even when encryption is paused.
2612      * XXX: what should be here? Was there code here that got deleted?
2613      */
2614 #endif
2615 
2616     /* Move to next connection event */
2617     if (ble_ll_conn_next_event(connsm)) {
2618         ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL);
2619         return;
2620     }
2621 
2622     /* Reset "per connection event" variables */
2623     connsm->cons_rxd_bad_crc = 0;
2624     connsm->csmflags.cfbit.pkt_rxd = 0;
2625 
2626     /* See if we need to start any control procedures */
2627     ble_ll_ctrl_chk_proc_start(connsm);
2628 
2629     /* Set initial schedule callback */
2630     connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
2631 
2632     /* XXX: I think all this fine for when we do connection updates, but
2633        we may want to force the first event to be scheduled. Not sure */
2634     /* Schedule the next connection event */
2635     while (ble_ll_sched_conn_reschedule(connsm)) {
2636         if (ble_ll_conn_next_event(connsm)) {
2637             ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL);
2638             return;
2639         }
2640     }
2641 
2642     /*
2643      * This is definitely not perfect but hopefully will be fine in regards to
2644      * the specification. We check the supervision timer at connection event
2645      * end. If the next connection event is going to start past the supervision
2646      * timeout we end the connection here. I guess this goes against the spec
2647      * in two ways:
2648      * 1) We are actually causing a supervision timeout before the time
2649      * specified. However, this is really a moot point because the supervision
2650      * timeout would have expired before we could possibly receive a packet.
2651      * 2) We may end the supervision timeout a bit later than specified as
2652      * we only check this at event end and a bad CRC could cause us to continue
2653      * the connection event longer than the supervision timeout. Given that two
2654      * bad CRC's consecutively ends the connection event, I dont regard this as
2655      * a big deal but it could cause a slightly longer supervision timeout.
2656      */
2657     if (connsm->conn_state == BLE_LL_CONN_STATE_CREATED) {
2658         tmo = (uint32_t)connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS * 6UL;
2659         ble_err = BLE_ERR_CONN_ESTABLISHMENT;
2660     } else {
2661         tmo = connsm->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000UL;
2662         ble_err = BLE_ERR_CONN_SPVN_TMO;
2663     }
2664     /* XXX: Convert to ticks to usecs calculation instead??? */
2665     tmo = os_cputime_usecs_to_ticks(tmo);
2666     if ((int32_t)(connsm->anchor_point - connsm->last_rxd_pdu_cputime) >= tmo) {
2667         ble_ll_conn_end(connsm, ble_err);
2668         return;
2669     }
2670 
2671     /* If we have completed packets, send an event */
2672     ble_ll_conn_num_comp_pkts_event_send(connsm);
2673 
2674     /* If we have features and there's pending HCI command, send an event */
2675     if (connsm->csmflags.cfbit.pending_hci_rd_features &&
2676                                         connsm->csmflags.cfbit.rxd_features) {
2677         ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS);
2678         connsm->csmflags.cfbit.pending_hci_rd_features = 0;
2679     }
2680 }
2681 
2682 /**
2683  * Update the connection request PDU with the address type and address of
2684  * advertiser we are going to send connect request to.
2685  *
2686  * @param m
2687  * @param adva
2688  * @param addr_type     Address type of ADVA from received advertisement.
2689  * @param inita
2690  * @param inita_type     Address type of INITA from received advertisement.
2691 
2692  * @param txoffset      The tx window offset for this connection
2693  */
2694 static void
ble_ll_conn_req_pdu_update(struct os_mbuf * m,uint8_t * adva,uint8_t addr_type,uint8_t * inita,uint8_t inita_type,uint16_t txoffset,int rpa_index)2695 ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type,
2696                            uint8_t *inita, uint8_t inita_type,
2697                            uint16_t txoffset, int rpa_index)
2698 {
2699     uint8_t hdr;
2700     uint8_t *dptr;
2701     uint8_t *addr;
2702     struct ble_mbuf_hdr *ble_hdr;
2703     struct ble_ll_conn_sm *connsm;
2704 
2705 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
2706     int is_rpa;
2707     struct ble_ll_resolv_entry *rl;
2708 #endif
2709 
2710     BLE_LL_ASSERT(m != NULL);
2711 
2712     /* clear txadd/rxadd bits only */
2713     ble_hdr = BLE_MBUF_HDR_PTR(m);
2714     hdr = ble_hdr->txinfo.hdr_byte &
2715           ~(BLE_ADV_PDU_HDR_RXADD_MASK | BLE_ADV_PDU_HDR_TXADD_MASK);
2716 
2717     if (addr_type) {
2718         /* Set random address */
2719         hdr |= BLE_ADV_PDU_HDR_RXADD_MASK;
2720     }
2721 
2722     dptr = m->om_data;
2723 
2724     if (inita) {
2725         memcpy(dptr, inita, BLE_DEV_ADDR_LEN);
2726         if (inita_type) {
2727             hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
2728         }
2729     } else {
2730         /* Get pointer to our device address */
2731         connsm = g_ble_ll_conn_create_sm;
2732         if ((connsm->own_addr_type & 1) == 0) {
2733             addr = g_dev_addr;
2734         } else {
2735             hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
2736             addr = g_random_addr;
2737         }
2738 
2739     /* XXX: do this ahead of time? Calculate the local rpa I mean */
2740 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
2741         if (connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
2742             rl = NULL;
2743             is_rpa = ble_ll_is_rpa(adva, addr_type);
2744             if (is_rpa) {
2745                 if (rpa_index >= 0) {
2746                     rl = &g_ble_ll_resolv_list[rpa_index];
2747                 }
2748             } else {
2749                 if (ble_ll_resolv_enabled()) {
2750                     rl = ble_ll_resolv_list_find(adva, addr_type);
2751                 }
2752             }
2753 
2754             /*
2755              * If peer in on resolving list, we use RPA generated with Local IRK
2756              * from resolving list entry. In other case, we need to use our identity
2757              * address (see  Core 5.0, Vol 6, Part B, section 6.4).
2758              */
2759             if (rl) {
2760                 hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
2761                 ble_ll_resolv_get_priv_addr(rl, 1, dptr);
2762                 addr = NULL;
2763             }
2764         }
2765 #endif
2766 
2767         if (addr) {
2768             memcpy(dptr, addr, BLE_DEV_ADDR_LEN);
2769         }
2770     }
2771 
2772     memcpy(dptr + BLE_DEV_ADDR_LEN, adva, BLE_DEV_ADDR_LEN);
2773     put_le16(dptr + 20, txoffset);
2774 
2775     /* Set BLE transmit header */
2776     ble_hdr->txinfo.hdr_byte = hdr;
2777 }
2778 
2779 /* Returns true if the address matches the connection peer address having in
2780  * mind privacy mode
2781  */
2782 static int
ble_ll_conn_is_peer_adv(uint8_t addr_type,uint8_t * adva,int index)2783 ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva, int index)
2784 {
2785     int rc;
2786     uint8_t *peer_addr;
2787     struct ble_ll_conn_sm *connsm;
2788 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
2789     struct ble_ll_resolv_entry *rl;
2790 #endif
2791 
2792     /* XXX: Deal with different types of random addresses here! */
2793     connsm = g_ble_ll_conn_create_sm;
2794     if (!connsm) {
2795         return 0;
2796     }
2797 
2798     switch (connsm->peer_addr_type) {
2799     /* Fall-through intentional */
2800     case BLE_HCI_CONN_PEER_ADDR_PUBLIC:
2801     case BLE_HCI_CONN_PEER_ADDR_RANDOM:
2802         if (addr_type == connsm->peer_addr_type) {
2803 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
2804                 /* Peer uses its identity address. Let's verify privacy mode.
2805                  *
2806                  * Note: Core Spec 5.0 Vol 6, Part B
2807                  * If the Host has added the peer device to the resolving list
2808                  * with an all-zero peer IRK, the Controller shall only accept
2809                  * the peer's identity address.
2810                  */
2811             if (ble_ll_resolv_enabled()) {
2812                 rl = ble_ll_resolv_list_find(adva, addr_type);
2813                 if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
2814                         ble_ll_resolv_irk_nonzero(rl->rl_peer_irk)) {
2815                     return 0;
2816                 }
2817             }
2818 #endif
2819             peer_addr = adva;
2820             break;
2821         }
2822 
2823 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
2824         /* Check if peer uses RPA. If so and it match, use it as controller
2825          * supports privacy mode
2826          */
2827         if ((index < 0) ||
2828             (g_ble_ll_resolv_list[index].rl_addr_type != connsm->peer_addr_type)) {
2829             return 0;
2830         }
2831 
2832         peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr;
2833 
2834         break;
2835     case BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT:
2836         if ((index < 0) ||
2837             (g_ble_ll_resolv_list[index].rl_addr_type != 0)) {
2838             return 0;
2839         }
2840         peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr;
2841         break;
2842     case BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT:
2843         if ((index < 0) ||
2844             (g_ble_ll_resolv_list[index].rl_addr_type != 1)) {
2845             return 0;
2846         }
2847         peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr;
2848         break;
2849 #endif
2850     default:
2851         peer_addr = NULL;
2852         break;
2853     }
2854 
2855     rc = 0;
2856     if (peer_addr) {
2857         if (!memcmp(peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN)) {
2858             rc = 1;
2859         }
2860     }
2861 
2862     return rc;
2863 }
2864 
2865 /**
2866  * Called when a connect request transmission is done.
2867  *
2868  * Context: ISR
2869  *
2870  * @param arg
2871  */
2872 static void
ble_ll_conn_req_txend(void * arg)2873 ble_ll_conn_req_txend(void *arg)
2874 {
2875     ble_ll_state_set(BLE_LL_STATE_STANDBY);
2876 }
2877 
2878 static void
ble_ll_conn_req_txend_init(void * arg)2879 ble_ll_conn_req_txend_init(void *arg)
2880 {
2881     ble_ll_state_set(BLE_LL_STATE_INITIATING);
2882 }
2883 /**
2884  * Send a connection requestion to an advertiser
2885  *
2886  * Context: Interrupt
2887  *
2888  * @param addr_type Address type of advertiser
2889  * @param adva Address of advertiser
2890  */
2891 int
ble_ll_conn_request_send(uint8_t addr_type,uint8_t * adva,uint8_t inita_type,uint8_t * inita,uint16_t txoffset,int rpa_index,uint8_t end_trans)2892 ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva,
2893                          uint8_t inita_type, uint8_t *inita,
2894                          uint16_t txoffset,
2895                          int rpa_index, uint8_t end_trans)
2896 {
2897     struct os_mbuf *m;
2898     int rc;
2899 
2900     /* XXX: TODO: assume we are already on correct phy */
2901     m = ble_ll_scan_get_pdu();
2902     ble_ll_conn_req_pdu_update(m, adva, addr_type, inita, inita_type,
2903                                txoffset, rpa_index);
2904     if (end_trans == BLE_PHY_TRANSITION_NONE) {
2905         ble_phy_set_txend_cb(ble_ll_conn_req_txend, NULL);
2906     } else {
2907         ble_phy_set_txend_cb(ble_ll_conn_req_txend_init, NULL);
2908     }
2909     rc = ble_phy_tx(ble_ll_tx_flat_mbuf_pducb, m, end_trans);
2910     return rc;
2911 }
2912 
2913 /**
2914  * Called when a schedule item overlaps the currently running connection
2915  * event. This generally should not happen, but if it does we stop the
2916  * current connection event to let the schedule item run.
2917  *
2918  * NOTE: the phy has been disabled as well as the wfr timer before this is
2919  * called.
2920  */
2921 void
ble_ll_conn_event_halt(void)2922 ble_ll_conn_event_halt(void)
2923 {
2924     ble_ll_state_set(BLE_LL_STATE_STANDBY);
2925     if (g_ble_ll_conn_cur_sm) {
2926         g_ble_ll_conn_cur_sm->csmflags.cfbit.pkt_rxd = 0;
2927         ble_ll_event_send(&g_ble_ll_conn_cur_sm->conn_ev_end);
2928         g_ble_ll_conn_cur_sm = NULL;
2929     }
2930 }
2931 
2932 /**
2933  * Process a received PDU while in the initiating state.
2934  *
2935  * Context: Link Layer task.
2936  *
2937  * @param pdu_type
2938  * @param rxbuf
2939  * @param ble_hdr
2940  */
2941 void
ble_ll_init_rx_pkt_in(uint8_t pdu_type,uint8_t * rxbuf,struct ble_mbuf_hdr * ble_hdr)2942 ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
2943                       struct ble_mbuf_hdr *ble_hdr)
2944 {
2945 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
2946     int8_t rpa_index;
2947 #endif
2948     uint8_t addr_type;
2949     uint8_t *addr;
2950     uint8_t *adv_addr;
2951     struct ble_ll_conn_sm *connsm;
2952     int ext_adv_mode = -1;
2953 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
2954     struct ble_ll_aux_data *aux_data = ble_hdr->rxinfo.user_data;
2955 
2956     /*
2957      * Let's take the reference for handover to LL.
2958      * There shall be one more, if not something went very wrong
2959      */
2960     if (aux_data && !ble_ll_scan_aux_data_unref(aux_data)) {
2961         BLE_LL_ASSERT(0);
2962     }
2963 
2964 #endif
2965 
2966     /* Get the connection state machine we are trying to create */
2967     connsm = g_ble_ll_conn_create_sm;
2968     if (!connsm) {
2969         return;
2970     }
2971 
2972     if (!BLE_MBUF_HDR_CRC_OK(ble_hdr)) {
2973         goto scan_continue;
2974     }
2975 
2976 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
2977     if (BLE_MBUF_HDR_AUX_INVALID(ble_hdr)) {
2978         goto scan_continue;
2979     }
2980 
2981     if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) {
2982         if (BLE_MBUF_HDR_WAIT_AUX(ble_hdr)) {
2983             /* Just continue scanning. We are waiting for AUX */
2984             if (!ble_ll_sched_aux_scan(ble_hdr, connsm->scansm, aux_data)) {
2985                 ble_ll_scan_aux_data_ref(aux_data);
2986                 ble_ll_scan_chk_resume();
2987                 return;
2988             }
2989             goto scan_continue;
2990         }
2991     }
2992 
2993     if (CONN_F_AUX_CONN_REQ(connsm)) {
2994         /* Wait for connection response */
2995         if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) {
2996             return;
2997         }
2998     }
2999 #endif
3000 
3001     /* If we have sent a connect request, we need to enter CONNECTION state */
3002     if (connsm && CONN_F_CONN_REQ_TXD(connsm)) {
3003         /* Set address of advertiser to which we are connecting. */
3004 
3005         if (ble_ll_scan_adv_decode_addr(pdu_type, rxbuf, ble_hdr,
3006                                         &adv_addr, &addr_type,
3007                                         NULL, NULL, &ext_adv_mode)) {
3008             /* Something got wrong, keep trying to connect */
3009             goto scan_continue;
3010         }
3011 
3012         if (ble_ll_scan_whitelist_enabled()) {
3013 
3014 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
3015             /*
3016              * Did we resolve this address? If so, set correct peer address
3017              * and peer address type.
3018              */
3019             rpa_index = connsm->rpa_index;
3020 
3021             if (rpa_index >= 0) {
3022                 addr_type = g_ble_ll_resolv_list[rpa_index].rl_addr_type + 2;
3023                 addr = g_ble_ll_resolv_list[rpa_index].rl_identity_addr;
3024             } else {
3025                 addr = adv_addr;
3026             }
3027 #else
3028             addr = adv_addr;
3029 #endif
3030 
3031             connsm->peer_addr_type = addr_type;
3032             memcpy(connsm->peer_addr, addr, BLE_DEV_ADDR_LEN);
3033         }
3034 
3035         if (connsm->rpa_index >= 0) {
3036             ble_ll_scan_set_peer_rpa(rxbuf + BLE_LL_PDU_HDR_LEN);
3037 
3038 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
3039             /* Update resolving list with current peer RPA */
3040             ble_ll_resolv_set_peer_rpa(connsm->rpa_index, rxbuf + BLE_LL_PDU_HDR_LEN);
3041 #endif
3042         }
3043 
3044         /* Connection has been created. Stop scanning */
3045         g_ble_ll_conn_create_sm = NULL;
3046         ble_ll_scan_sm_stop(0);
3047 
3048         /* For AUX Connect CSA2 is mandatory. Otherwise we need to check bit
3049          * mask
3050          */
3051         if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
3052             ble_ll_conn_set_csa(connsm, 1);
3053         } else {
3054             ble_ll_conn_set_csa(connsm, rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK);
3055         }
3056 
3057 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3058 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
3059         /* Lets take last used phy */
3060         ble_ll_conn_init_phy(connsm, ble_hdr->rxinfo.phy);
3061 #endif
3062         ble_ll_scan_aux_data_unref(aux_data);
3063 #endif
3064         ble_ll_conn_created(connsm, NULL);
3065         return;
3066     }
3067 
3068 scan_continue:
3069 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3070     /* Drop last reference and keep continue to connect */
3071     ble_ll_scan_aux_data_unref(aux_data);
3072 #endif
3073     ble_ll_scan_chk_resume();
3074 }
3075 
3076 /**
3077  * Called when a receive PDU has started and we are in the initiating state.
3078  *
3079  * Context: Interrupt
3080  *
3081  * @param pdu_type
3082  * @param ble_hdr
3083  *
3084  * @return int
3085  *  0: we will not attempt to reply to this frame
3086  *  1: we may send a response to this frame.
3087  */
3088 int
ble_ll_init_rx_isr_start(uint8_t pdu_type,struct ble_mbuf_hdr * ble_hdr)3089 ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
3090 {
3091     struct ble_ll_conn_sm *connsm;
3092 
3093     connsm = g_ble_ll_conn_create_sm;
3094     if (!connsm) {
3095         return 0;
3096     }
3097 
3098     if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
3099         (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND ||
3100          pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP)) {
3101         return 1;
3102     }
3103 
3104 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3105     if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND &&
3106                                                 connsm->scansm->ext_scanning) {
3107         if (connsm->scansm->cur_aux_data) {
3108             STATS_INC(ble_ll_stats, aux_received);
3109         }
3110 
3111         ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV;
3112         return 1;
3113     }
3114 #endif
3115 
3116     return 0;
3117 }
3118 
3119 /**
3120  * Make a connect request PDU
3121  *
3122  * @param connsm
3123  */
3124 static void
ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm * connsm,uint8_t chan)3125 ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t chan)
3126 {
3127     uint8_t pdu_type;
3128     uint8_t *dptr;
3129     struct os_mbuf *m;
3130 
3131     m = ble_ll_scan_get_pdu();
3132     BLE_LL_ASSERT(m != NULL);
3133 
3134     /* Construct first PDU header byte */
3135     pdu_type = BLE_ADV_PDU_TYPE_CONNECT_REQ;
3136 
3137 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
3138     /* We need CSA2 bit only for legacy connect */
3139     if (chan >= BLE_PHY_NUM_DATA_CHANS) {
3140         pdu_type |= BLE_ADV_PDU_HDR_CHSEL;
3141     }
3142 #endif
3143 
3144     /* Set BLE transmit header */
3145     ble_ll_mbuf_init(m, BLE_CONNECT_REQ_LEN, pdu_type);
3146 
3147     /* Construct the connect request */
3148     dptr = m->om_data;
3149 
3150     /* Skip inita and adva advertiser's address as we dont know that yet */
3151     dptr += (2 * BLE_DEV_ADDR_LEN);
3152 
3153     /* Access address */
3154     put_le32(dptr, connsm->access_addr);
3155     dptr[4] = (uint8_t)connsm->crcinit;
3156     dptr[5] = (uint8_t)(connsm->crcinit >> 8);
3157     dptr[6] = (uint8_t)(connsm->crcinit >> 16);
3158     dptr[7] = connsm->tx_win_size;
3159     put_le16(dptr + 8, connsm->tx_win_off);
3160     put_le16(dptr + 10, connsm->conn_itvl);
3161     put_le16(dptr + 12, connsm->slave_latency);
3162     put_le16(dptr + 14, connsm->supervision_tmo);
3163     memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CONN_CHMAP_LEN);
3164     dptr[21] = connsm->hop_inc | (connsm->master_sca << 5);
3165 }
3166 
3167 /**
3168  * Called when a receive PDU has ended and we are in the initiating state.
3169  *
3170  * Context: Interrupt
3171  *
3172  * @param rxpdu
3173  * @param crcok
3174  * @param ble_hdr
3175  *
3176  * @return int
3177  *       < 0: Disable the phy after reception.
3178  *      == 0: Success. Do not disable the PHY.
3179  *       > 0: Do not disable PHY as that has already been done.
3180  */
3181 int
ble_ll_init_rx_isr_end(uint8_t * rxbuf,uint8_t crcok,struct ble_mbuf_hdr * ble_hdr)3182 ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
3183                        struct ble_mbuf_hdr *ble_hdr)
3184 {
3185     int rc;
3186     int resolved;
3187     int chk_wl;
3188     int index;
3189     uint8_t pdu_type;
3190     uint8_t addr_type;
3191     uint8_t peer_addr_type;
3192     uint8_t *adv_addr = NULL;
3193     uint8_t *peer;
3194     uint8_t *init_addr = NULL;
3195     uint8_t init_addr_type;
3196     uint8_t pyld_len;
3197     uint8_t inita_is_rpa;
3198     uint8_t conn_req_end_trans;
3199     struct os_mbuf *rxpdu;
3200     struct ble_ll_conn_sm *connsm;
3201 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
3202     struct ble_ll_resolv_entry *rl;
3203 #endif
3204 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3205     struct ble_ll_scan_sm *scansm;
3206     uint8_t phy;
3207 #endif
3208     int ext_adv_mode = -1;
3209 
3210     /* Get connection state machine to use if connection to be established */
3211     connsm = g_ble_ll_conn_create_sm;
3212 
3213     rc = -1;
3214     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
3215     pyld_len = rxbuf[1];
3216 
3217 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3218     scansm = connsm->scansm;
3219     if (scansm->cur_aux_data) {
3220         ble_hdr->rxinfo.user_data = scansm->cur_aux_data;
3221         scansm->cur_aux_data = NULL;
3222         if (ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data) == 0) {
3223             ble_hdr->rxinfo.user_data = 0;
3224             goto init_rx_isr_exit;
3225         }
3226     }
3227 #endif
3228 
3229     if (!crcok) {
3230 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3231         /* Invalid packet - make sure we do not wait for AUX_CONNECT_RSP */
3232         ble_ll_conn_reset_pending_aux_conn_rsp();
3233 #endif
3234 
3235         /* Ignore this packet */
3236         goto init_rx_isr_exit;
3237     }
3238 
3239 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3240     /* If we sent AUX_CONNECT_REQ, we only expect AUX_CONNECT_RSP here */
3241     if (CONN_F_AUX_CONN_REQ(connsm)) {
3242         if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) {
3243             STATS_INC(ble_ll_stats, aux_conn_rsp_err);
3244             CONN_F_CONN_REQ_TXD(connsm) = 0;
3245             CONN_F_AUX_CONN_REQ(connsm) = 0;
3246             ble_ll_sched_rmv_elem(&connsm->conn_sch);
3247         }
3248         goto init_rx_isr_exit;
3249     }
3250 #endif
3251 
3252     inita_is_rpa = 0;
3253 
3254 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3255     if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) {
3256         if (!scansm) {
3257             goto init_rx_isr_exit;
3258         }
3259         if (!scansm->ext_scanning) {
3260             goto init_rx_isr_exit;
3261         }
3262 
3263         rc = ble_ll_scan_get_aux_data(ble_hdr, rxbuf);
3264         if (rc < 0) {
3265             /* No memory or broken packet */
3266             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
3267             ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data);
3268             ble_hdr->rxinfo.user_data = NULL;
3269             goto init_rx_isr_exit;
3270         }
3271     }
3272 #endif
3273 
3274     /* Lets get addresses from advertising report*/
3275     if (ble_ll_scan_adv_decode_addr(pdu_type, rxbuf, ble_hdr,
3276                                     &adv_addr, &addr_type,
3277                                     &init_addr, &init_addr_type,
3278                                     &ext_adv_mode)) {
3279 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3280         ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
3281 #endif
3282         goto init_rx_isr_exit;
3283     }
3284 
3285     switch (pdu_type) {
3286     case BLE_ADV_PDU_TYPE_ADV_IND:
3287         break;
3288 
3289 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3290     case BLE_ADV_PDU_TYPE_ADV_EXT_IND:
3291         rc = -1;
3292 
3293         /* If this is not connectable adv mode, lets skip it */
3294         if (!(ext_adv_mode & BLE_LL_EXT_ADV_MODE_CONN)) {
3295             goto init_rx_isr_exit;
3296         }
3297 
3298         if (!adv_addr) {
3299             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT;
3300             goto init_rx_isr_exit;
3301         }
3302 
3303         if (!init_addr) {
3304             break;
3305         }
3306         /* if there is direct address lets fall down and check it.*/
3307         // no break
3308 #endif
3309     case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
3310         inita_is_rpa = (uint8_t)ble_ll_is_rpa(init_addr, init_addr_type);
3311         if (!inita_is_rpa) {
3312 
3313             /* Resolving will be done later. Check if identity InitA matches */
3314             if (!ble_ll_is_our_devaddr(init_addr, init_addr_type)) {
3315                 goto init_rx_isr_exit;
3316             }
3317         }
3318 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 0
3319         else {
3320             /* If privacy is off - reject RPA InitA*/
3321             goto init_rx_isr_exit;
3322         }
3323 #endif
3324 
3325         break;
3326     default:
3327         goto init_rx_isr_exit;
3328     }
3329 
3330     /* Should we send a connect request? */
3331     index = -1;
3332     peer = adv_addr;
3333     peer_addr_type = addr_type;
3334 
3335     resolved = 0;
3336     chk_wl = ble_ll_scan_whitelist_enabled();
3337 
3338 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
3339     if (ble_ll_is_rpa(adv_addr, addr_type) && ble_ll_resolv_enabled()) {
3340         index = ble_hw_resolv_list_match();
3341         if (index >= 0) {
3342             rl = &g_ble_ll_resolv_list[index];
3343 
3344             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED;
3345             connsm->rpa_index = index;
3346             peer = rl->rl_identity_addr;
3347             peer_addr_type = rl->rl_addr_type;
3348             resolved = 1;
3349 
3350             /* Assure privacy */
3351             if ((rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
3352                                         init_addr && !inita_is_rpa &&
3353                                         ble_ll_resolv_irk_nonzero(rl->rl_local_irk)) {
3354                 goto init_rx_isr_exit;
3355             }
3356 
3357             /*
3358              * If the InitA is a RPA, we must see if it resolves based on the
3359              * identity address of the resolved ADVA.
3360              */
3361             if (init_addr && inita_is_rpa &&
3362                             !ble_ll_resolv_rpa(init_addr,
3363                                                g_ble_ll_resolv_list[index].rl_local_irk)) {
3364                 goto init_rx_isr_exit;
3365             }
3366 
3367         } else {
3368             if (chk_wl) {
3369                 goto init_rx_isr_exit;
3370             }
3371 
3372             /* Could not resolved InitA */
3373             if (init_addr && inita_is_rpa) {
3374                 goto init_rx_isr_exit;
3375             }
3376         }
3377     } else if (init_addr) {
3378 
3379         /* If resolving is off and InitA is RPA we reject advertising */
3380         if (inita_is_rpa && !ble_ll_resolv_enabled()) {
3381             goto init_rx_isr_exit;
3382         }
3383 
3384         /* Let's see if we have IRK with that peer.*/
3385         rl = ble_ll_resolv_list_find(adv_addr, addr_type);
3386 
3387         /* Lets make sure privacy mode is correct together with InitA in case it
3388          * is identity address
3389          */
3390         if (rl && !inita_is_rpa &&
3391            (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
3392             ble_ll_resolv_irk_nonzero(rl->rl_local_irk)) {
3393             goto init_rx_isr_exit;
3394         }
3395 
3396         /*
3397          * If the InitA is a RPA, we must see if it resolves based on the
3398          * identity address of the resolved ADVA.
3399          */
3400         if (inita_is_rpa) {
3401             if (!rl || !ble_ll_resolv_rpa(init_addr, rl->rl_local_irk)) {
3402                 goto init_rx_isr_exit;
3403             }
3404         }
3405     }
3406 #endif
3407 
3408     /* Check filter policy */
3409     if (chk_wl) {
3410         if (!ble_ll_whitelist_match(peer, peer_addr_type, resolved)) {
3411             goto init_rx_isr_exit;
3412         }
3413     } else {
3414         /* Must match the connection address */
3415         if (!ble_ll_conn_is_peer_adv(addr_type, adv_addr, index)) {
3416             goto init_rx_isr_exit;
3417         }
3418     }
3419     ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH;
3420 
3421     /* For CONNECT_IND we don't go into RX state */
3422     conn_req_end_trans = BLE_PHY_TRANSITION_NONE;
3423 
3424 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3425     /* Check if we should send AUX_CONNECT_REQ and wait for AUX_CONNECT_RSP */
3426     if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
3427         conn_req_end_trans = BLE_PHY_TRANSITION_TX_RX;
3428     }
3429 
3430     if (connsm->scansm->ext_scanning) {
3431             phy = ble_hdr->rxinfo.phy;
3432 
3433             /* Update connection state machine with appropriate parameters for
3434              * certain PHY
3435              */
3436             ble_ll_conn_ext_set_params(connsm,
3437                                        &connsm->initial_params.params[phy - 1],
3438                                        phy);
3439 
3440     }
3441 #endif
3442 
3443     /* Create the connection request */
3444     ble_ll_conn_req_pdu_make(connsm, ble_hdr->rxinfo.channel);
3445 
3446     if (ble_ll_sched_master_new(connsm, ble_hdr, pyld_len)) {
3447         STATS_INC(ble_ll_conn_stats, cant_set_sched);
3448         goto init_rx_isr_exit;
3449     }
3450 
3451     /* Setup to transmit the connect request */
3452     rc = ble_ll_conn_request_send(addr_type, adv_addr,
3453                                   init_addr_type, init_addr,
3454                                   connsm->tx_win_off, index,
3455                                   conn_req_end_trans);
3456     if (rc) {
3457         ble_ll_sched_rmv_elem(&connsm->conn_sch);
3458         goto init_rx_isr_exit;
3459     }
3460 
3461     if (init_addr && !inita_is_rpa) {
3462         connsm->inita_identity_used = 1;
3463     }
3464 
3465     CONN_F_CONN_REQ_TXD(connsm) = 1;
3466 
3467 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3468     if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
3469         /* Lets wait for AUX_CONNECT_RSP */
3470         CONN_F_AUX_CONN_REQ(connsm) = 1;
3471         /* Keep aux data until we get scan response */
3472         scansm->cur_aux_data = ble_hdr->rxinfo.user_data;
3473         ble_hdr->rxinfo.user_data = NULL;
3474         STATS_INC(ble_ll_stats, aux_conn_req_tx);
3475     }
3476 #endif
3477 
3478     STATS_INC(ble_ll_conn_stats, conn_req_txd);
3479 
3480 init_rx_isr_exit:
3481 
3482 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
3483     if (ble_hdr->rxinfo.user_data) {
3484         ble_ll_scan_aux_data_ref(ble_hdr->rxinfo.user_data);
3485     }
3486 #endif
3487     /*
3488      * We have to restart receive if we cant hand up pdu. We return 0 so that
3489      * the phy does not get disabled.
3490      */
3491     rxpdu = ble_ll_rxpdu_alloc(pyld_len + BLE_LL_PDU_HDR_LEN);
3492     if (rxpdu == NULL) {
3493         /*
3494          * XXX: possible allocate the PDU when we start initiating?
3495          * I cannot say I like this solution, but if we cannot allocate a PDU
3496          * to hand up to the LL, we need to remove the connection we just
3497          * scheduled since the connection state machine will not get processed
3498          * by link layer properly. For now, just remove it from the scheduler
3499          */
3500         if (CONN_F_CONN_REQ_TXD(connsm) == 1) {
3501             CONN_F_CONN_REQ_TXD(connsm) = 0;
3502             CONN_F_AUX_CONN_REQ(connsm) = 0;
3503             ble_ll_sched_rmv_elem(&connsm->conn_sch);
3504         }
3505         ble_phy_restart_rx();
3506         rc = 0;
3507     } else {
3508         ble_phy_rxpdu_copy(rxbuf, rxpdu);
3509         ble_ll_rx_pdu_in(rxpdu);
3510     }
3511 
3512     if (rc) {
3513         ble_ll_state_set(BLE_LL_STATE_STANDBY);
3514     }
3515 
3516     return rc;
3517 }
3518 
3519 /**
3520  * Function called when a timeout has occurred for a connection. There are
3521  * two types of timeouts: a connection supervision timeout and control
3522  * procedure timeout.
3523  *
3524  * Context: Link Layer task
3525  *
3526  * @param connsm
3527  * @param ble_err
3528  */
3529 void
ble_ll_conn_timeout(struct ble_ll_conn_sm * connsm,uint8_t ble_err)3530 ble_ll_conn_timeout(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
3531 {
3532     int was_current;
3533     os_sr_t sr;
3534 
3535     was_current = 0;
3536     OS_ENTER_CRITICAL(sr);
3537     if (g_ble_ll_conn_cur_sm == connsm) {
3538         ble_ll_conn_current_sm_over(NULL);
3539         was_current = 1;
3540     }
3541     OS_EXIT_CRITICAL(sr);
3542 
3543     /* Check if we need to resume scanning */
3544     if (was_current) {
3545         ble_ll_scan_chk_resume();
3546     }
3547 
3548     ble_ll_conn_end(connsm, ble_err);
3549 }
3550 
3551 /**
3552  * Called when a data channel PDU has started that matches the access
3553  * address of the current connection. Note that the CRC of the PDU has not
3554  * been checked yet.
3555  *
3556  * Context: Interrupt
3557  *
3558  * @param rxhdr
3559  */
3560 int
ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr * rxhdr,uint32_t aa)3561 ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa)
3562 {
3563     struct ble_ll_conn_sm *connsm;
3564 
3565     /*
3566      * Disable wait for response timer since we receive a response. We dont
3567      * care if this is the response we were waiting for or not; the code
3568      * called at receive end will deal with ending the connection event
3569      * if needed
3570      */
3571     ble_ll_wfr_disable();
3572     connsm = g_ble_ll_conn_cur_sm;
3573     if (connsm) {
3574         /* Double check access address. Better match connection state machine */
3575         if (aa != connsm->access_addr) {
3576             STATS_INC(ble_ll_conn_stats, rx_data_pdu_bad_aa);
3577             ble_ll_state_set(BLE_LL_STATE_STANDBY);
3578             ble_ll_event_send(&connsm->conn_ev_end);
3579             g_ble_ll_conn_cur_sm = NULL;
3580             return -1;
3581         }
3582 
3583         /* Set connection handle in mbuf header */
3584         rxhdr->rxinfo.handle = connsm->conn_handle;
3585 
3586         /* Set flag denoting we have received a packet in connection event */
3587         connsm->csmflags.cfbit.pkt_rxd = 1;
3588 
3589         /* Connection is established */
3590         connsm->conn_state = BLE_LL_CONN_STATE_ESTABLISHED;
3591 
3592         /* Set anchor point (and last) if 1st rxd frame in connection event */
3593         if (connsm->csmflags.cfbit.slave_set_last_anchor) {
3594             connsm->csmflags.cfbit.slave_set_last_anchor = 0;
3595             connsm->last_anchor_point = rxhdr->beg_cputime;
3596             connsm->anchor_point = connsm->last_anchor_point;
3597             connsm->anchor_point_usecs = rxhdr->rem_usecs;
3598         }
3599     }
3600     return 1;
3601 }
3602 
3603 /**
3604  * Called from the Link Layer task when a data PDU has been received
3605  *
3606  * Context: Link layer task
3607  *
3608  * @param rxpdu Pointer to received pdu
3609  * @param rxpdu Pointer to ble mbuf header of received pdu
3610  */
3611 void
ble_ll_conn_rx_data_pdu(struct os_mbuf * rxpdu,struct ble_mbuf_hdr * hdr)3612 ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
3613 {
3614     uint8_t hdr_byte;
3615     uint8_t rxd_sn;
3616     uint8_t *rxbuf;
3617     uint8_t llid;
3618     uint16_t acl_len;
3619     uint16_t acl_hdr;
3620     struct ble_ll_conn_sm *connsm;
3621 
3622     if (BLE_MBUF_HDR_CRC_OK(hdr)) {
3623         /* XXX: there is a chance that the connection was thrown away and
3624            re-used before processing packets here. Fix this. */
3625         /* We better have a connection state machine */
3626         connsm = ble_ll_conn_find_active_conn(hdr->rxinfo.handle);
3627         if (connsm) {
3628             /* Check state machine */
3629             ble_ll_conn_chk_csm_flags(connsm);
3630 
3631             /* Validate rx data pdu */
3632             rxbuf = rxpdu->om_data;
3633             hdr_byte = rxbuf[0];
3634             acl_len = rxbuf[1];
3635             llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
3636 
3637             /*
3638              * Check that the LLID and payload length are reasonable.
3639              * Empty payload is only allowed for LLID == 01b.
3640              *  */
3641             if ((llid == 0) ||
3642                 ((acl_len == 0) && (llid != BLE_LL_LLID_DATA_FRAG))) {
3643                 STATS_INC(ble_ll_conn_stats, rx_bad_llid);
3644                 goto conn_rx_data_pdu_end;
3645             }
3646 
3647 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
3648             /* Check if PDU is allowed when encryption is started. If not,
3649              * terminate connection.
3650              *
3651              * Reference: Core 5.0, Vol 6, Part B, 5.1.3.1
3652              */
3653             if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT) &&
3654                     !ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
3655                 ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
3656                 goto conn_rx_data_pdu_end;
3657             }
3658 #endif
3659 
3660 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
3661             /*
3662              * Reset authenticated payload timeout if valid MIC. NOTE: we dont
3663              * check the MIC failure bit as that would have terminated the
3664              * connection
3665              */
3666             if ((connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED) &&
3667                 CONN_F_LE_PING_SUPP(connsm) && (acl_len != 0)) {
3668                 ble_ll_conn_auth_pyld_timer_start(connsm);
3669             }
3670 #endif
3671 
3672             /* Update RSSI */
3673             connsm->conn_rssi = hdr->rxinfo.rssi;
3674 
3675             /*
3676              * If we are a slave, we can only start to use slave latency
3677              * once we have received a NESN of 1 from the master
3678              */
3679             if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
3680                 if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) {
3681                     connsm->csmflags.cfbit.allow_slave_latency = 1;
3682                 }
3683             }
3684 
3685             /*
3686              * Discard the received PDU if the sequence number is the same
3687              * as the last received sequence number
3688              */
3689             rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
3690             if (rxd_sn != connsm->last_rxd_sn) {
3691                 /* Update last rxd sn */
3692                 connsm->last_rxd_sn = rxd_sn;
3693 
3694                 /* No need to do anything if empty pdu */
3695                 if ((llid == BLE_LL_LLID_DATA_FRAG) && (acl_len == 0)) {
3696                     goto conn_rx_data_pdu_end;
3697                 }
3698 
3699 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
3700                 /*
3701                  * XXX: should we check to see if we are in a state where we
3702                  * might expect to get an encrypted PDU?
3703                  */
3704                 if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
3705                     STATS_INC(ble_ll_conn_stats, mic_failures);
3706                     ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
3707                     goto conn_rx_data_pdu_end;
3708                 }
3709 #endif
3710 
3711                 if (llid == BLE_LL_LLID_CTRL) {
3712                     /* Process control frame */
3713                     STATS_INC(ble_ll_conn_stats, rx_ctrl_pdus);
3714                     if (ble_ll_ctrl_rx_pdu(connsm, rxpdu)) {
3715                         STATS_INC(ble_ll_conn_stats, rx_malformed_ctrl_pdus);
3716                     }
3717                 } else {
3718                     /* Count # of received l2cap frames and byes */
3719                     STATS_INC(ble_ll_conn_stats, rx_l2cap_pdus);
3720                     STATS_INCN(ble_ll_conn_stats, rx_l2cap_bytes, acl_len);
3721 
3722                     /* NOTE: there should be at least two bytes available */
3723                     BLE_LL_ASSERT(OS_MBUF_LEADINGSPACE(rxpdu) >= 2);
3724                     os_mbuf_prepend(rxpdu, 2);
3725                     rxbuf = rxpdu->om_data;
3726 
3727                     acl_hdr = (llid << 12) | connsm->conn_handle;
3728                     put_le16(rxbuf, acl_hdr);
3729                     put_le16(rxbuf + 2, acl_len);
3730                     ble_hci_trans_ll_acl_tx(rxpdu);
3731                 }
3732 
3733                 /* NOTE: we dont free the mbuf since we handed it off! */
3734                 return;
3735             } else {
3736                 STATS_INC(ble_ll_conn_stats, data_pdu_rx_dup);
3737             }
3738         } else {
3739             STATS_INC(ble_ll_conn_stats, no_conn_sm);
3740         }
3741     }
3742 
3743     /* Free buffer */
3744 conn_rx_data_pdu_end:
3745     os_mbuf_free_chain(rxpdu);
3746 }
3747 
3748 /**
3749  * Called when a packet has been received while in the connection state.
3750  *
3751  * Context: Interrupt
3752  *
3753  * @param rxpdu
3754  * @param crcok
3755  *
3756  * @return int
3757  *       < 0: Disable the phy after reception.
3758  *      == 0: Success. Do not disable the PHY.
3759  *       > 0: Do not disable PHY as that has already been done.
3760  */
3761 int
ble_ll_conn_rx_isr_end(uint8_t * rxbuf,struct ble_mbuf_hdr * rxhdr)3762 ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
3763 {
3764     int rc;
3765     int is_ctrl;
3766     uint8_t hdr_byte;
3767     uint8_t hdr_sn;
3768     uint8_t hdr_nesn;
3769     uint8_t conn_sn;
3770     uint8_t conn_nesn;
3771     uint8_t reply;
3772     uint8_t rem_bytes;
3773     uint8_t opcode = 0;
3774     uint8_t rx_pyld_len;
3775     uint32_t begtime;
3776     uint32_t add_usecs;
3777     struct os_mbuf *txpdu;
3778     struct ble_ll_conn_sm *connsm;
3779     struct os_mbuf *rxpdu;
3780     struct ble_mbuf_hdr *txhdr;
3781     int rx_phy_mode;
3782 
3783     /* Retrieve the header and payload length */
3784     hdr_byte = rxbuf[0];
3785     rx_pyld_len = rxbuf[1];
3786 
3787     /*
3788      * We need to attempt to allocate a buffer here. The reason we do this
3789      * now is that we should not ack the packet if we have no receive
3790      * buffers available. We want to free up our transmit PDU if it was
3791      * acked, but we should not ack the received frame if we cant hand it up.
3792      * NOTE: we hand up empty pdu's to the LL task!
3793      */
3794     rxpdu = ble_ll_rxpdu_alloc(rx_pyld_len + BLE_LL_PDU_HDR_LEN);
3795 
3796     /*
3797      * We should have a current connection state machine. If we dont, we just
3798      * hand the packet to the higher layer to count it.
3799      */
3800     rc = -1;
3801     connsm = g_ble_ll_conn_cur_sm;
3802     if (!connsm) {
3803         STATS_INC(ble_ll_conn_stats, rx_data_pdu_no_conn);
3804         goto conn_exit;
3805     }
3806 
3807     /*
3808      * Calculate the end time of the received PDU. NOTE: this looks strange
3809      * but for the 32768 crystal we add the time it takes to send the packet
3810      * to the 'additional usecs' field to save some calculations.
3811      */
3812     begtime = rxhdr->beg_cputime;
3813 #if BLE_LL_BT5_PHY_SUPPORTED
3814     rx_phy_mode = connsm->phy_data.rx_phy_mode;
3815 #else
3816     rx_phy_mode = BLE_PHY_MODE_1M;
3817 #endif
3818     add_usecs = rxhdr->rem_usecs +
3819             ble_ll_pdu_tx_time_get(rx_pyld_len, rx_phy_mode);
3820 
3821     /*
3822      * Check the packet CRC. A connection event can continue even if the
3823      * received PDU does not pass the CRC check. If we receive two consecutive
3824      * CRC errors we end the conection event.
3825      */
3826     if (!BLE_MBUF_HDR_CRC_OK(rxhdr)) {
3827         /*
3828          * Increment # of consecutively received CRC errors. If more than
3829          * one we will end the connection event.
3830          */
3831         ++connsm->cons_rxd_bad_crc;
3832         if (connsm->cons_rxd_bad_crc >= 2) {
3833             reply = 0;
3834         } else {
3835             if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
3836                 reply = CONN_F_LAST_TXD_MD(connsm);
3837             } else {
3838                 /* A slave always responds with a packet */
3839                 reply = 1;
3840             }
3841         }
3842     } else {
3843         /* Reset consecutively received bad crcs (since this one was good!) */
3844         connsm->cons_rxd_bad_crc = 0;
3845 
3846         /* Set last valid received pdu time (resets supervision timer) */
3847         connsm->last_rxd_pdu_cputime = begtime +
3848                                         os_cputime_usecs_to_ticks(add_usecs);
3849 
3850         /*
3851          * Check for valid LLID before proceeding. We have seen some weird
3852          * things with the PHY where the CRC is OK but we dont have a valid
3853          * LLID. This should really never happen but if it does we will just
3854          * bail. An error stat will get incremented at the LL.
3855          */
3856         if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == 0) {
3857             goto conn_exit;
3858         }
3859 
3860         /* Set last received header byte */
3861         connsm->last_rxd_hdr_byte = hdr_byte;
3862 
3863         is_ctrl = 0;
3864         if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
3865             is_ctrl = 1;
3866             opcode = rxbuf[2];
3867         }
3868 
3869         /*
3870          * If SN bit from header does not match NESN in connection, this is
3871          * a resent PDU and should be ignored.
3872          */
3873         hdr_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
3874         conn_nesn = connsm->next_exp_seqnum;
3875         if (rxpdu && ((hdr_sn && conn_nesn) || (!hdr_sn && !conn_nesn))) {
3876             connsm->next_exp_seqnum ^= 1;
3877 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
3878             if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxbuf)) {
3879                 ++connsm->enc_data.rx_pkt_cntr;
3880             }
3881 #endif
3882         }
3883 
3884         ble_ll_trace_u32x2(BLE_LL_TRACE_ID_CONN_RX, connsm->tx_seqnum,
3885                            !!(hdr_byte & BLE_LL_DATA_HDR_NESN_MASK));
3886 
3887         /*
3888          * Check NESN bit from header. If same as tx seq num, the transmission
3889          * is acknowledged. Otherwise we need to resend this PDU.
3890          */
3891         if (CONN_F_EMPTY_PDU_TXD(connsm) || connsm->cur_tx_pdu) {
3892             hdr_nesn = hdr_byte & BLE_LL_DATA_HDR_NESN_MASK;
3893             conn_sn = connsm->tx_seqnum;
3894             if ((hdr_nesn && conn_sn) || (!hdr_nesn && !conn_sn)) {
3895                 /* We did not get an ACK. Must retry the PDU */
3896                 STATS_INC(ble_ll_conn_stats, data_pdu_txf);
3897             } else {
3898                 /* Transmit success */
3899                 connsm->tx_seqnum ^= 1;
3900                 STATS_INC(ble_ll_conn_stats, data_pdu_txg);
3901 
3902                 /* If we transmitted the empty pdu, clear flag */
3903                 if (CONN_F_EMPTY_PDU_TXD(connsm)) {
3904                     CONN_F_EMPTY_PDU_TXD(connsm) = 0;
3905                     goto chk_rx_terminate_ind;
3906                 }
3907 
3908                 /*
3909                  * Determine if we should remove packet from queue or if there
3910                  * are more fragments to send.
3911                  */
3912                 txpdu = connsm->cur_tx_pdu;
3913                 if (txpdu) {
3914 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
3915                     if (connsm->enc_data.tx_encrypted) {
3916                         ++connsm->enc_data.tx_pkt_cntr;
3917                     }
3918 #endif
3919                     txhdr = BLE_MBUF_HDR_PTR(txpdu);
3920                     if ((txhdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK)
3921                         == BLE_LL_LLID_CTRL) {
3922                         connsm->cur_tx_pdu = NULL;
3923                         /* Note: the mbuf is freed by this call */
3924                         rc = ble_ll_ctrl_tx_done(txpdu, connsm);
3925                         if (rc) {
3926                             /* Means we transmitted a TERMINATE_IND */
3927                             goto conn_exit;
3928                         } else {
3929                             goto chk_rx_terminate_ind;
3930                         }
3931                     }
3932 
3933                     /* Increment offset based on number of bytes sent */
3934                     txhdr->txinfo.offset += txhdr->txinfo.pyld_len;
3935                     if (txhdr->txinfo.offset >= OS_MBUF_PKTLEN(txpdu)) {
3936                         /* If l2cap pdu, increment # of completed packets */
3937                         if (txhdr->txinfo.pyld_len != 0) {
3938 #if (BLETEST_THROUGHPUT_TEST == 1)
3939                             bletest_completed_pkt(connsm->conn_handle);
3940 #endif
3941                             ++connsm->completed_pkts;
3942                             if (connsm->completed_pkts > 2) {
3943                                 ble_npl_eventq_put(&g_ble_ll_data.ll_evq,
3944                                                    &g_ble_ll_data.ll_comp_pkt_ev);
3945                             }
3946                         }
3947                         os_mbuf_free_chain(txpdu);
3948                         connsm->cur_tx_pdu = NULL;
3949                     } else {
3950                         rem_bytes = OS_MBUF_PKTLEN(txpdu) - txhdr->txinfo.offset;
3951                         /* Adjust payload for max TX time and octets */
3952 
3953 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
3954                         if (is_ctrl && (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE)
3955                                         && (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) {
3956                             connsm->phy_tx_transition = rxbuf[3];
3957                         }
3958 #endif
3959 
3960                         rem_bytes = ble_ll_conn_adjust_pyld_len(connsm, rem_bytes);
3961                         txhdr->txinfo.pyld_len = rem_bytes;
3962                     }
3963                 }
3964             }
3965         }
3966 
3967         /* Should we continue connection event? */
3968         /* If this is a TERMINATE_IND, we have to reply */
3969 chk_rx_terminate_ind:
3970         /* If we received a terminate IND, we must set some flags */
3971         if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND)
3972                     && (rx_pyld_len == (1 + BLE_LL_CTRL_TERMINATE_IND_LEN))) {
3973             connsm->csmflags.cfbit.terminate_ind_rxd = 1;
3974             connsm->rxd_disconnect_reason = rxbuf[3];
3975         }
3976 
3977         if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
3978             reply = CONN_F_LAST_TXD_MD(connsm) || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK);
3979         } else {
3980             /* A slave always replies */
3981             reply = 1;
3982 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
3983             if (is_ctrl && (opcode == BLE_LL_CTRL_PAUSE_ENC_RSP)) {
3984                 connsm->enc_data.enc_state = CONN_ENC_S_PAUSED;
3985             }
3986 #endif
3987         }
3988     }
3989 
3990     /* If reply flag set, send data pdu and continue connection event */
3991     rc = -1;
3992     if (rx_pyld_len && CONN_F_ENCRYPTED(connsm)) {
3993         rx_pyld_len += BLE_LL_DATA_MIC_LEN;
3994     }
3995     if (reply && ble_ll_conn_can_send_next_pdu(connsm, begtime, add_usecs)) {
3996         rc = ble_ll_conn_tx_data_pdu(connsm);
3997     }
3998 
3999 conn_exit:
4000     /* Copy the received pdu and hand it up */
4001     if (rxpdu) {
4002         ble_phy_rxpdu_copy(rxbuf, rxpdu);
4003         ble_ll_rx_pdu_in(rxpdu);
4004     }
4005 
4006     /* Send link layer a connection end event if over */
4007     if (rc) {
4008         ble_ll_conn_current_sm_over(connsm);
4009     }
4010 
4011     return rc;
4012 }
4013 
4014 /**
4015  * Called to adjust payload length to fit into max effective octets and TX time
4016  * on current PHY.
4017  */
4018 /**
4019  * Called to enqueue a packet on the transmit queue of a connection. Should
4020  * only be called by the controller.
4021  *
4022  * Context: Link Layer
4023  *
4024  *
4025  * @param connsm
4026  * @param om
4027  */
4028 void
ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm * connsm,struct os_mbuf * om,uint8_t hdr_byte,uint8_t length)4029 ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om,
4030                         uint8_t hdr_byte, uint8_t length)
4031 {
4032     os_sr_t sr;
4033     struct os_mbuf_pkthdr *pkthdr;
4034     struct ble_mbuf_hdr *ble_hdr;
4035     int lifo;
4036 
4037     /* Set mbuf length and packet length if a control PDU */
4038     if (hdr_byte == BLE_LL_LLID_CTRL) {
4039         om->om_len = length;
4040         OS_MBUF_PKTHDR(om)->omp_len = length;
4041     }
4042 
4043     /* Set BLE transmit header */
4044     ble_hdr = BLE_MBUF_HDR_PTR(om);
4045     ble_hdr->txinfo.flags = 0;
4046     ble_hdr->txinfo.offset = 0;
4047     ble_hdr->txinfo.hdr_byte = hdr_byte;
4048 
4049     /*
4050      * Initial payload length is calculate when packet is dequeued, there's no
4051      * need to do this now.
4052      */
4053 
4054     lifo = 0;
4055 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
4056     if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
4057         uint8_t llid;
4058 
4059         /*
4060          * If this is one of the following types we need to insert it at
4061          * head of queue.
4062          */
4063         llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
4064         if (llid == BLE_LL_LLID_CTRL) {
4065             switch (om->om_data[0]) {
4066             case BLE_LL_CTRL_TERMINATE_IND:
4067             case BLE_LL_CTRL_REJECT_IND:
4068             case BLE_LL_CTRL_REJECT_IND_EXT:
4069             case BLE_LL_CTRL_START_ENC_REQ:
4070             case BLE_LL_CTRL_START_ENC_RSP:
4071                 lifo = 1;
4072                 break;
4073             case BLE_LL_CTRL_PAUSE_ENC_RSP:
4074                 if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
4075                     lifo = 1;
4076                 }
4077                 break;
4078             case BLE_LL_CTRL_ENC_REQ:
4079             case BLE_LL_CTRL_ENC_RSP:
4080                 /* If encryption has been paused, we don't want to send any packets from the
4081                  * TX queue, as they would go unencrypted.
4082                  */
4083                 if (connsm->enc_data.enc_state == CONN_ENC_S_PAUSED) {
4084                     lifo = 1;
4085                 }
4086                 break;
4087             default:
4088                 break;
4089             }
4090         }
4091     }
4092 #endif
4093 
4094     /* Add to transmit queue for the connection */
4095     pkthdr = OS_MBUF_PKTHDR(om);
4096     OS_ENTER_CRITICAL(sr);
4097     if (lifo) {
4098         STAILQ_INSERT_HEAD(&connsm->conn_txq, pkthdr, omp_next);
4099     } else {
4100         STAILQ_INSERT_TAIL(&connsm->conn_txq, pkthdr, omp_next);
4101     }
4102     OS_EXIT_CRITICAL(sr);
4103 }
4104 
4105 /**
4106  * Data packet from host.
4107  *
4108  * Context: Link Layer task
4109  *
4110  * @param om
4111  * @param handle
4112  * @param length
4113  *
4114  * @return int
4115  */
4116 void
ble_ll_conn_tx_pkt_in(struct os_mbuf * om,uint16_t handle,uint16_t length)4117 ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length)
4118 {
4119     uint8_t hdr_byte;
4120     uint16_t conn_handle;
4121     uint16_t pb;
4122     struct ble_ll_conn_sm *connsm;
4123 
4124     /* See if we have an active matching connection handle */
4125     conn_handle = handle & 0x0FFF;
4126     connsm = ble_ll_conn_find_active_conn(conn_handle);
4127     if (connsm) {
4128         /* Construct LL header in buffer (NOTE: pb already checked) */
4129         pb = handle & 0x3000;
4130         if (pb == 0) {
4131             hdr_byte = BLE_LL_LLID_DATA_START;
4132         } else {
4133             hdr_byte = BLE_LL_LLID_DATA_FRAG;
4134         }
4135 
4136         /* Add to total l2cap pdus enqueue */
4137         STATS_INC(ble_ll_conn_stats, l2cap_enqueued);
4138 
4139         /* Clear flags field in BLE header */
4140         ble_ll_conn_enqueue_pkt(connsm, om, hdr_byte, length);
4141     } else {
4142         /* No connection found! */
4143         STATS_INC(ble_ll_conn_stats, handle_not_found);
4144         os_mbuf_free_chain(om);
4145     }
4146 }
4147 
4148 /**
4149  * Called to set the global channel mask that we use for all connections.
4150  *
4151  * @param num_used_chans
4152  * @param chanmap
4153  */
4154 void
ble_ll_conn_set_global_chanmap(uint8_t num_used_chans,uint8_t * chanmap)4155 ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, uint8_t *chanmap)
4156 {
4157     struct ble_ll_conn_sm *connsm;
4158     struct ble_ll_conn_global_params *conn_params;
4159 
4160     /* Do nothing if same channel map */
4161     conn_params = &g_ble_ll_conn_params;
4162     if (!memcmp(conn_params->master_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN)) {
4163         return;
4164     }
4165 
4166     /* Change channel map and cause channel map update procedure to start */
4167     conn_params->num_used_chans = num_used_chans;
4168     memcpy(conn_params->master_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN);
4169 
4170     /* Perform channel map update */
4171     SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) {
4172         if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
4173             ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD);
4174         }
4175     }
4176 }
4177 
4178 /**
4179  * Called when a device has received a connect request while advertising and
4180  * the connect request has passed the advertising filter policy and is for
4181  * us. This will start a connection in the slave role assuming that we dont
4182  * already have a connection with this device and that the connect request
4183  * parameters are valid.
4184  *
4185  * Context: Link Layer
4186  *
4187  * @param rxbuf Pointer to received Connect Request PDU
4188  *
4189  * @return 0: connection not started; 1 connecton started
4190  */
4191 int
ble_ll_conn_slave_start(uint8_t * rxbuf,uint8_t pat,struct ble_mbuf_hdr * rxhdr,bool force_csa2)4192 ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr,
4193                         bool force_csa2)
4194 {
4195     int rc;
4196     uint32_t temp;
4197     uint32_t crcinit;
4198     uint8_t *inita;
4199     uint8_t *dptr;
4200     struct ble_ll_conn_sm *connsm;
4201 
4202     /* Ignore the connection request if we are already connected*/
4203     inita = rxbuf + BLE_LL_PDU_HDR_LEN;
4204     SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) {
4205         if (!memcmp(&connsm->peer_addr, inita, BLE_DEV_ADDR_LEN)) {
4206             if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
4207                 if (connsm->peer_addr_type & 1) {
4208                     return 0;
4209                 }
4210             } else {
4211                 if ((connsm->peer_addr_type & 1) == 0) {
4212                     return 0;
4213                 }
4214             }
4215         }
4216     }
4217 
4218     /* Allocate a connection. If none available, dont do anything */
4219     connsm = ble_ll_conn_sm_get();
4220     if (connsm == NULL) {
4221         return 0;
4222     }
4223 
4224     /* Set the pointer at the start of the connection data */
4225     dptr = rxbuf + BLE_LL_CONN_REQ_ADVA_OFF + BLE_DEV_ADDR_LEN;
4226 
4227     /* Set connection state machine information */
4228     connsm->access_addr = get_le32(dptr);
4229     crcinit = dptr[6];
4230     crcinit = (crcinit << 8) | dptr[5];
4231     crcinit = (crcinit << 8) | dptr[4];
4232     connsm->crcinit = crcinit;
4233     connsm->tx_win_size = dptr[7];
4234     connsm->tx_win_off = get_le16(dptr + 8);
4235     connsm->conn_itvl = get_le16(dptr + 10);
4236     connsm->slave_latency = get_le16(dptr + 12);
4237     connsm->supervision_tmo = get_le16(dptr + 14);
4238     memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CONN_CHMAP_LEN);
4239     connsm->hop_inc = dptr[21] & 0x1F;
4240     connsm->master_sca = dptr[21] >> 5;
4241 
4242     /* Error check parameters */
4243     if ((connsm->tx_win_off > connsm->conn_itvl) ||
4244         (connsm->conn_itvl < BLE_HCI_CONN_ITVL_MIN) ||
4245         (connsm->conn_itvl > BLE_HCI_CONN_ITVL_MAX) ||
4246         (connsm->tx_win_size < BLE_LL_CONN_TX_WIN_MIN) ||
4247         (connsm->slave_latency > BLE_LL_CONN_SLAVE_LATENCY_MAX)) {
4248         goto err_slave_start;
4249     }
4250 
4251     /* Slave latency cannot cause a supervision timeout */
4252     temp = (connsm->slave_latency + 1) * (connsm->conn_itvl * 2) *
4253             BLE_LL_CONN_ITVL_USECS;
4254     if ((connsm->supervision_tmo * 10000) <= temp ) {
4255         goto err_slave_start;
4256     }
4257 
4258     /*
4259      * The transmit window must be less than or equal to the lesser of 10
4260      * msecs or the connection interval minus 1.25 msecs.
4261      */
4262     temp = connsm->conn_itvl - 1;
4263     if (temp > 8) {
4264         temp = 8;
4265     }
4266     if (connsm->tx_win_size > temp) {
4267         goto err_slave_start;
4268     }
4269 
4270     /* Set the address of device that we are connecting with */
4271     memcpy(&connsm->peer_addr, inita, BLE_DEV_ADDR_LEN);
4272     connsm->peer_addr_type = pat;
4273 
4274     /* Calculate number of used channels; make sure it meets min requirement */
4275     connsm->num_used_chans = ble_ll_conn_calc_used_chans(connsm->chanmap);
4276     if (connsm->num_used_chans < 2) {
4277         goto err_slave_start;
4278     }
4279 
4280     /* Start the connection state machine */
4281     connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE;
4282     ble_ll_conn_sm_new(connsm);
4283 
4284 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
4285     /* Use the same PHY as we received CONNECT_REQ on */
4286     ble_ll_conn_init_phy(connsm, rxhdr->rxinfo.phy);
4287 #endif
4288 
4289     ble_ll_conn_set_csa(connsm,
4290                         force_csa2 || (rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK));
4291 
4292     /* Set initial schedule callback */
4293     connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
4294     rc = ble_ll_conn_created(connsm, rxhdr);
4295     if (!rc) {
4296         SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
4297         STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
4298     }
4299     return rc;
4300 
4301 err_slave_start:
4302     STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
4303     STATS_INC(ble_ll_conn_stats, slave_rxd_bad_conn_req_params);
4304     return 0;
4305 }
4306 
4307 #define MAX_TIME_UNCODED(_maxbytes) \
4308         ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \
4309                                BLE_PHY_MODE_1M);
4310 #define MAX_TIME_CODED(_maxbytes) \
4311         ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \
4312                                BLE_PHY_MODE_CODED_125KBPS);
4313 
4314 /**
4315  * Called to reset the connection module. When this function is called the
4316  * scheduler has been stopped and the phy has been disabled. The LL should
4317  * be in the standby state.
4318  *
4319  * Context: Link Layer task
4320  */
4321 void
ble_ll_conn_module_reset(void)4322 ble_ll_conn_module_reset(void)
4323 {
4324     uint8_t max_phy_pyld;
4325     uint16_t maxbytes;
4326     struct ble_ll_conn_sm *connsm;
4327     struct ble_ll_conn_global_params *conn_params;
4328 
4329     /* Kill the current one first (if one is running) */
4330     if (g_ble_ll_conn_cur_sm) {
4331         connsm = g_ble_ll_conn_cur_sm;
4332         g_ble_ll_conn_cur_sm = NULL;
4333         ble_ll_conn_end(connsm, BLE_ERR_SUCCESS);
4334     }
4335 
4336     /* Free the global connection complete event if there is one */
4337     if (g_ble_ll_conn_comp_ev) {
4338         ble_hci_trans_buf_free(g_ble_ll_conn_comp_ev);
4339         g_ble_ll_conn_comp_ev = NULL;
4340     }
4341 
4342     /* Reset connection we are attempting to create */
4343     g_ble_ll_conn_create_sm = NULL;
4344 
4345     /* Now go through and end all the connections */
4346     while (1) {
4347         connsm = SLIST_FIRST(&g_ble_ll_conn_active_list);
4348         if (!connsm) {
4349             break;
4350         }
4351         ble_ll_conn_end(connsm, BLE_ERR_SUCCESS);
4352     }
4353 
4354     /* Get the maximum supported PHY PDU size from the PHY */
4355     max_phy_pyld = ble_phy_max_data_pdu_pyld();
4356 
4357     /* Configure the global LL parameters */
4358     conn_params = &g_ble_ll_conn_params;
4359 
4360     maxbytes = min(MYNEWT_VAL(BLE_LL_SUPP_MAX_RX_BYTES), max_phy_pyld);
4361     conn_params->supp_max_rx_octets = maxbytes;
4362 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
4363     conn_params->supp_max_rx_time = MAX_TIME_CODED(maxbytes);
4364 #else
4365     conn_params->supp_max_rx_time = MAX_TIME_UNCODED(maxbytes);
4366 #endif
4367 
4368     maxbytes = min(MYNEWT_VAL(BLE_LL_SUPP_MAX_TX_BYTES), max_phy_pyld);
4369     conn_params->supp_max_tx_octets = maxbytes;
4370 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
4371     conn_params->supp_max_tx_time = MAX_TIME_CODED(maxbytes);
4372 #else
4373     conn_params->supp_max_tx_time = MAX_TIME_UNCODED(maxbytes);
4374 #endif
4375 
4376     maxbytes = min(MYNEWT_VAL(BLE_LL_CONN_INIT_MAX_TX_BYTES), max_phy_pyld);
4377     conn_params->conn_init_max_tx_octets = maxbytes;
4378     conn_params->conn_init_max_tx_time = MAX_TIME_UNCODED(maxbytes);
4379     conn_params->conn_init_max_tx_time_uncoded = MAX_TIME_UNCODED(maxbytes);
4380     conn_params->conn_init_max_tx_time_coded = MAX_TIME_CODED(maxbytes);
4381 
4382     conn_params->sugg_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
4383     conn_params->sugg_tx_time = BLE_LL_CONN_SUPP_TIME_MIN;
4384 
4385     /* Mask in all channels by default */
4386     conn_params->num_used_chans = BLE_PHY_NUM_DATA_CHANS;
4387     memset(conn_params->master_chan_map, 0xff, BLE_LL_CONN_CHMAP_LEN - 1);
4388     conn_params->master_chan_map[4] = 0x1f;
4389 
4390     /* Reset statistics */
4391     STATS_RESET(ble_ll_conn_stats);
4392 }
4393 
4394 /* Initialize the connection module */
4395 void
ble_ll_conn_module_init(void)4396 ble_ll_conn_module_init(void)
4397 {
4398     int rc;
4399     uint16_t i;
4400     struct ble_ll_conn_sm *connsm;
4401 
4402     /* Initialize list of active conections */
4403     SLIST_INIT(&g_ble_ll_conn_active_list);
4404     STAILQ_INIT(&g_ble_ll_conn_free_list);
4405 
4406     /*
4407      * Take all the connections off the free memory pool and add them to
4408      * the free connection list, assigning handles in linear order. Note:
4409      * the specification allows a handle of zero; we just avoid using it.
4410      */
4411     connsm = &g_ble_ll_conn_sm[0];
4412     for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) {
4413 
4414         memset(connsm, 0, sizeof(struct ble_ll_conn_sm));
4415         connsm->conn_handle = i + 1;
4416         STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
4417 
4418         /* Initialize fixed schedule elements */
4419         connsm->conn_sch.sched_type = BLE_LL_SCHED_TYPE_CONN;
4420         connsm->conn_sch.cb_arg = connsm;
4421         ++connsm;
4422     }
4423 
4424     /* Register connection statistics */
4425     rc = stats_init_and_reg(STATS_HDR(ble_ll_conn_stats),
4426                             STATS_SIZE_INIT_PARMS(ble_ll_conn_stats, STATS_SIZE_32),
4427                             STATS_NAME_INIT_PARMS(ble_ll_conn_stats),
4428                             "ble_ll_conn");
4429     BLE_LL_ASSERT(rc == 0);
4430 
4431     /* Call reset to finish reset of initialization */
4432     ble_ll_conn_module_reset();
4433 }
4434