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