From 36f344d0692f379f79837392ea9d7f17acc0fff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Mon, 12 Mar 2018 14:09:15 +0100 Subject: [PATCH 01/25] nimble/ll: Don't stop CONN_PARAM_REQ procedure on collision This fixes following scenario for test case LL/CONN/MAS/BV-26 * nimble is master on the link and started connection parameter procedure, * peer sends connection parameter request * nimble replies with ext reject err=lmp collision error After this nimble shall wait for response. This patch should fixed that --- nimble/controller/src/ble_ll_ctrl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 50c0b724a..63172c06b 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2453,8 +2453,15 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; case BLE_LL_CTRL_REJECT_IND_EXT: if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { - connsm->reject_reason = txpdu->om_data[2]; - connsm->csmflags.cfbit.host_expects_upd_event = 1; + /* If rejecting opcode is BLE_LL_CTRL_PROC_CONN_PARAM_REQ and + * reason is LMP collision that means we are master on the link and + * peer wanted to start procedure which we already started. + * Let's wait for response and do not close procedure. */ + if (txpdu->om_data[1] == BLE_LL_CTRL_CONN_PARM_REQ && + txpdu->om_data[2] != BLE_ERR_LMP_COLLISION) { + connsm->reject_reason = txpdu->om_data[2]; + connsm->csmflags.cfbit.host_expects_upd_event = 1; + } } #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) { From 396a4bf593b56dbfa8034872c6613b537b5d7614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 30 Aug 2018 15:21:18 +0200 Subject: [PATCH 02/25] nimble/ll: Fix handling EXT_REJECT_IND on CONN_PARAM_REQ If peer sends back EXT_REJECT_IND on CONN_PARAM_REQ, Nimble controller should send LL_CONN_UPDATE_IND and stop the LL procedure This fixes LL/CON/MAS/BV-29 --- nimble/controller/src/ble_ll_ctrl.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 63172c06b..068ef5a71 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1458,11 +1458,12 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, * @param dptr * @param opcode */ -static void +static int ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, - uint8_t opcode) + uint8_t opcode, uint8_t *rspdata) { uint8_t ble_error; + uint8_t rsp_opcode = BLE_ERR_MAX; /* Get error out of received PDU */ if (opcode == BLE_LL_CTRL_REJECT_IND) { @@ -1476,8 +1477,15 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, switch (connsm->cur_ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_PARAM_REQ: if (opcode == BLE_LL_CTRL_REJECT_IND_EXT) { - ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); - ble_ll_hci_ev_conn_update(connsm, ble_error); + /* As a master we should send connection update indication in this point */ + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; + ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); + connsm->reject_reason = BLE_ERR_SUCCESS; + } else { + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); + ble_ll_hci_ev_conn_update(connsm, ble_error); + } } break; #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) @@ -1503,6 +1511,8 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, default: break; } + + return rsp_opcode; } /** @@ -2338,7 +2348,8 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) /* Fall-through intentional... */ case BLE_LL_CTRL_REJECT_IND: case BLE_LL_CTRL_REJECT_IND_EXT: - ble_ll_ctrl_rx_reject_ind(connsm, dptr, opcode); + /* Sometimes reject triggers sending other LL CTRL msg */ + rsp_opcode = ble_ll_ctrl_rx_reject_ind(connsm, dptr, opcode, rspdata); break; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) case BLE_LL_CTRL_PHY_REQ: From f2ec62f81631c413c305e182927e88713ecf41c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 30 Aug 2018 15:38:55 +0200 Subject: [PATCH 03/25] nimble/ll: Fix handling LL_UNKNOWN_RSP on LL_CONN_PARAM_REQ Make sure to send LL_CONN_UPDATE_IND if peer response with LL_UNKNOWN_RSP on LL_CONN_PARAM_REQ while being master on the link This fixes LL/CON/MAS/BV-81 --- nimble/controller/src/ble_ll_ctrl.c | 186 +++++++++++++++------------- 1 file changed, 97 insertions(+), 89 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 068ef5a71..b4373262e 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -356,6 +356,91 @@ conn_param_pdu_exit: return rsp_opcode; } +/** + * Called to make a connection update request LL control PDU + * + * Context: Link Layer + * + * @param connsm + * @param rsp + */ +static void +ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, + struct ble_ll_conn_params *cp) +{ + uint16_t instant; + uint32_t dt; + uint32_t num_old_ce; + uint32_t new_itvl_usecs; + uint32_t old_itvl_usecs; + struct hci_conn_update *hcu; + struct ble_ll_conn_upd_req *req; + + /* + * Set instant. We set the instant to the current event counter plus + * the amount of slave latency as the slave may not be listening + * at every connection interval and we are not sure when the connect + * request will actually get sent. We add one more event plus the + * minimum as per the spec of 6 connection events. + */ + instant = connsm->event_cntr + connsm->slave_latency + 6 + 1; + + /* + * XXX: This should change in the future, but for now we will just + * start the new instant at the same anchor using win offset 0. + */ + /* Copy parameters in connection update structure */ + hcu = &connsm->conn_param_req; + req = &connsm->conn_update_req; + if (cp) { + /* XXX: so we need to make the new anchor point some time away + * from txwinoffset by some amount of msecs. Not sure how to do + that here. We dont need to, but we should. */ + /* Calculate offset from requested offsets (if any) */ + if (cp->offset0 != 0xFFFF) { + new_itvl_usecs = cp->interval_max * BLE_LL_CONN_ITVL_USECS; + old_itvl_usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; + if ((int16_t)(cp->ref_conn_event_cnt - instant) >= 0) { + num_old_ce = cp->ref_conn_event_cnt - instant; + dt = old_itvl_usecs * num_old_ce; + dt += (cp->offset0 * BLE_LL_CONN_ITVL_USECS); + dt = dt % new_itvl_usecs; + } else { + num_old_ce = instant - cp->ref_conn_event_cnt; + dt = old_itvl_usecs * num_old_ce; + dt -= (cp->offset0 * BLE_LL_CONN_ITVL_USECS); + dt = dt % new_itvl_usecs; + dt = new_itvl_usecs - dt; + } + req->winoffset = dt / BLE_LL_CONN_TX_WIN_USECS; + } else { + req->winoffset = 0; + } + req->interval = cp->interval_max; + req->timeout = cp->timeout; + req->latency = cp->latency; + req->winsize = 1; + } else { + req->interval = hcu->conn_itvl_max; + req->timeout = hcu->supervision_timeout; + req->latency = hcu->conn_latency; + req->winoffset = 0; + req->winsize = connsm->tx_win_size; + } + req->instant = instant; + + /* XXX: make sure this works for the connection parameter request proc. */ + pyld[0] = req->winsize; + put_le16(pyld + 1, req->winoffset); + put_le16(pyld + 3, req->interval); + put_le16(pyld + 5, req->latency); + put_le16(pyld + 7, req->timeout); + put_le16(pyld + 9, instant); + + /* Set flag in state machine to denote we have scheduled an update */ + connsm->csmflags.cfbit.conn_update_sched = 1; +} + /** * Called to process and UNKNOWN_RSP LL control packet. * @@ -363,8 +448,8 @@ conn_param_pdu_exit: * * @param dptr */ -static void -ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) +static int +ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspdata) { uint8_t ctrl_proc; uint8_t opcode; @@ -383,8 +468,14 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) case BLE_LL_CTRL_SLAVE_FEATURE_REQ: ctrl_proc = BLE_LL_CTRL_PROC_FEATURE_XCHG; break; - case BLE_LL_CTRL_CONN_PARM_RSP: case BLE_LL_CTRL_CONN_PARM_REQ: + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); + connsm->reject_reason = BLE_ERR_SUCCESS; + return BLE_LL_CTRL_CONN_UPDATE_IND; + } + /* note: fall-through intentional */ + case BLE_LL_CTRL_CONN_PARM_RSP: ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ; break; case BLE_LL_CTRL_PING_REQ: @@ -418,6 +509,8 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) connsm->csmflags.cfbit.pending_hci_rd_features = 0; } } + + return BLE_ERR_MAX; } #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -1336,91 +1429,6 @@ ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) connsm->csmflags.cfbit.chanmap_update_scheduled = 1; } -/** - * Called to make a connection update request LL control PDU - * - * Context: Link Layer - * - * @param connsm - * @param rsp - */ -static void -ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, - struct ble_ll_conn_params *cp) -{ - uint16_t instant; - uint32_t dt; - uint32_t num_old_ce; - uint32_t new_itvl_usecs; - uint32_t old_itvl_usecs; - struct hci_conn_update *hcu; - struct ble_ll_conn_upd_req *req; - - /* - * Set instant. We set the instant to the current event counter plus - * the amount of slave latency as the slave may not be listening - * at every connection interval and we are not sure when the connect - * request will actually get sent. We add one more event plus the - * minimum as per the spec of 6 connection events. - */ - instant = connsm->event_cntr + connsm->slave_latency + 6 + 1; - - /* - * XXX: This should change in the future, but for now we will just - * start the new instant at the same anchor using win offset 0. - */ - /* Copy parameters in connection update structure */ - hcu = &connsm->conn_param_req; - req = &connsm->conn_update_req; - if (cp) { - /* XXX: so we need to make the new anchor point some time away - * from txwinoffset by some amount of msecs. Not sure how to do - that here. We dont need to, but we should. */ - /* Calculate offset from requested offsets (if any) */ - if (cp->offset0 != 0xFFFF) { - new_itvl_usecs = cp->interval_max * BLE_LL_CONN_ITVL_USECS; - old_itvl_usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; - if ((int16_t)(cp->ref_conn_event_cnt - instant) >= 0) { - num_old_ce = cp->ref_conn_event_cnt - instant; - dt = old_itvl_usecs * num_old_ce; - dt += (cp->offset0 * BLE_LL_CONN_ITVL_USECS); - dt = dt % new_itvl_usecs; - } else { - num_old_ce = instant - cp->ref_conn_event_cnt; - dt = old_itvl_usecs * num_old_ce; - dt -= (cp->offset0 * BLE_LL_CONN_ITVL_USECS); - dt = dt % new_itvl_usecs; - dt = new_itvl_usecs - dt; - } - req->winoffset = dt / BLE_LL_CONN_TX_WIN_USECS; - } else { - req->winoffset = 0; - } - req->interval = cp->interval_max; - req->timeout = cp->timeout; - req->latency = cp->latency; - req->winsize = 1; - } else { - req->interval = hcu->conn_itvl_max; - req->timeout = hcu->supervision_timeout; - req->latency = hcu->conn_latency; - req->winoffset = 0; - req->winsize = connsm->tx_win_size; - } - req->instant = instant; - - /* XXX: make sure this works for the connection parameter request proc. */ - pyld[0] = req->winsize; - put_le16(pyld + 1, req->winoffset); - put_le16(pyld + 3, req->interval); - put_le16(pyld + 5, req->latency); - put_le16(pyld + 7, req->timeout); - put_le16(pyld + 9, instant); - - /* Set flag in state machine to denote we have scheduled an update */ - connsm->csmflags.cfbit.conn_update_sched = 1; -} - /** * Called to respond to a LL control PDU connection parameter request or * response. @@ -2280,7 +2288,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) } break; case BLE_LL_CTRL_UNKNOWN_RSP: - ble_ll_ctrl_proc_unk_rsp(connsm, dptr); + rsp_opcode = ble_ll_ctrl_proc_unk_rsp(connsm, dptr, rspdata); break; case BLE_LL_CTRL_FEATURE_REQ: rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf, opcode); From f9564708182071ae5b9ba6ac46250b38497a6223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 31 Aug 2018 11:49:05 +0200 Subject: [PATCH 04/25] nimble/ll: Fix error code on connection update request If features has been exchanged and it is already known that peer does not support Connection Parameters Request procedure, controller shall return command status with code (0x1A) according to spec Bluetoot 5.0 Vol 6, 5.1.7 It fixes LL/CON/SLA/BV-86 --- nimble/controller/src/ble_ll_conn_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 5c086fbf3..92039e4c4 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -853,7 +853,7 @@ ble_ll_conn_hci_update(uint8_t *cmdbuf) /* See if this feature is supported on both sides */ if ((connsm->conn_features & BLE_LL_FEAT_CONN_PARM_REQ) == 0) { if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - return BLE_ERR_CMD_DISALLOWED; + return BLE_ERR_UNSUPP_REM_FEATURE; } ctrl_proc = BLE_LL_CTRL_PROC_CONN_UPDATE; } else { From acde4fe8cf4d66cacb3cbd545f74c33b1fb55cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 31 Aug 2018 13:46:42 +0200 Subject: [PATCH 05/25] nimble/ll: Fix missing directed flag --- nimble/controller/src/ble_ll_scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index e6a47a31b..13106b12c 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1793,6 +1793,7 @@ ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, out_evt->dir_addr_type = ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK); i += BLE_LL_EXT_ADV_TARGETA_SIZE; + out_evt->evt_type |= BLE_HCI_ADV_DIRECT_MASK; } if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_RFU_BIT)) { From 79001dd00a6dc1ba00bce509d7cd04edb7534675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 31 Aug 2018 14:35:34 +0200 Subject: [PATCH 06/25] nimble/ll: Verify length of Terminate Ind Make sure Terminate ind has correct len. Otherwise do not procced but reply with LL_UNKNOWN_RSP This should fix LL/PAC/SLA/BI-01 and LL/PAC/MAS/BI-01 --- nimble/controller/src/ble_ll_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 3528940f1..c3fe28463 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3907,7 +3907,8 @@ chk_rx_terminate_ind: } /* If we received a terminate IND, we must set some flags */ - if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND)) { + if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND) + && (rx_pyld_len == BLE_LL_CTRL_TERMINATE_IND_LEN)) { connsm->csmflags.cfbit.terminate_ind_rxd = 1; connsm->rxd_disconnect_reason = rxbuf[3]; reply = 1; From d332d31fdbbcba6892e47d907676d6b00eeb5a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 7 Sep 2018 16:15:00 +0200 Subject: [PATCH 07/25] nimble/ll: Fix error code in read remote feature event If connection is dropped and read remote feature was in progress let us send this event before disconnection complete event and with actually error code and not the fixed one as it was so far. This should fixed certification test LL/CONN/MAS/BV-19 --- nimble/controller/src/ble_ll_conn.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index c3fe28463..0d25c34a9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2130,6 +2130,15 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) connsm->csmflags.cfbit.pending_hci_rd_features = 0; } + /* + * If there is still pending read features request HCI command, send an + * event to complete it. + */ + if (connsm->csmflags.cfbit.pending_hci_rd_features) { + ble_ll_hci_ev_rd_rem_used_feat(connsm, ble_err); + connsm->csmflags.cfbit.pending_hci_rd_features = 0; + } + /* * We need to send a disconnection complete event. Connection Complete for * canceling connection creation is sent from LE Create Connection Cancel @@ -2143,15 +2152,6 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) ble_ll_disconn_comp_event_send(connsm, ble_err); } - /* - * If there is still pending read features request HCI command, send an - * event to complete it. - */ - if (connsm->csmflags.cfbit.pending_hci_rd_features) { - ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_UNK_CONN_ID); - connsm->csmflags.cfbit.pending_hci_rd_features = 0; - } - /* Put connection state machine back on free list */ STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); From e713c3fb84d5cda5021961518ce3f15145d10d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Mon, 10 Sep 2018 13:58:55 +0200 Subject: [PATCH 08/25] nimble/ll: Start LL response timer on PHY REQ as a slave If master does not end PHY Update procedure, Slave is responsible to drop the link. It fixes test LL/CON/SLA/BV-51 --- nimble/controller/src/ble_ll_ctrl.c | 60 +++++++++++++++++------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index b4373262e..b7d28404c 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -513,6 +513,36 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * return BLE_ERR_MAX; } +/** + * Callback when LL control procedure times out (for a given connection). If + * this is called, it means that we need to end the connection because it + * has not responded to a LL control request. + * + * Context: Link Layer + * + * @param arg Pointer to connection state machine. + */ +void +ble_ll_ctrl_proc_rsp_timer_cb(struct ble_npl_event *ev) +{ + /* Control procedure has timed out. Kill the connection */ + ble_ll_conn_timeout((struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev), + BLE_ERR_LMP_LL_RSP_TMO); +} + +static void +ble_ll_ctrl_start_rsp_timer(struct ble_ll_conn_sm *connsm) +{ + ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, + &g_ble_ll_data.ll_evq, + ble_ll_ctrl_proc_rsp_timer_cb, + connsm); + + /* Re-start timer. Control procedure timeout is 40 seconds */ + ble_npl_callout_reset(&connsm->ctrl_proc_rsp_timer, + ble_npl_time_ms_to_ticks32(BLE_LL_CTRL_PROC_TIMEOUT_MS)); +} + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) @@ -793,6 +823,10 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, CONN_F_PEER_PHY_UPDATE(connsm) = 1; ble_ll_ctrl_phy_req_rsp_make(connsm, rsp); rsp_opcode = BLE_LL_CTRL_PHY_RSP; + + /* Start response timer */ + connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE; + ble_ll_ctrl_start_rsp_timer(connsm); } return rsp_opcode; } @@ -1824,23 +1858,6 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } } -/** - * Callback when LL control procedure times out (for a given connection). If - * this is called, it means that we need to end the connection because it - * has not responded to a LL control request. - * - * Context: Link Layer - * - * @param arg Pointer to connection state machine. - */ -void -ble_ll_ctrl_proc_rsp_timer_cb(struct ble_npl_event *ev) -{ - /* Control procedure has timed out. Kill the connection */ - ble_ll_conn_timeout((struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev), - BLE_ERR_LMP_LL_RSP_TMO); -} - /** * Initiate LL control procedure. * @@ -2038,14 +2055,7 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc) /* Initialize the procedure response timeout */ if (ctrl_proc != BLE_LL_CTRL_PROC_CHAN_MAP_UPD) { - ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, - &g_ble_ll_data.ll_evq, - ble_ll_ctrl_proc_rsp_timer_cb, - connsm); - - /* Re-start timer. Control procedure timeout is 40 seconds */ - ble_npl_callout_reset(&connsm->ctrl_proc_rsp_timer, - ble_npl_time_ms_to_ticks32(BLE_LL_CTRL_PROC_TIMEOUT_MS)); + ble_ll_ctrl_start_rsp_timer(connsm); } } } From 7a94855661d9bbafb6e24c40983e5b7687f0b7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Mon, 10 Sep 2018 15:43:54 +0200 Subject: [PATCH 09/25] nimble/ll: Fix parameter check on HCI SET PHY command When tx_phys or rx_phys is not supported by controller, controller should respond with Unsupported Feature or Parameter Value (0x11) This patch fixes certification test LL/CON/SLA/BV-40 --- nimble/controller/src/ble_ll_hci.c | 52 ++++++++++++++++++------------ 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 3d4ae900f..07f520bf2 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -321,16 +321,21 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen) * @param txphy Pointer to output tx phy mask * @param rxphy Pointer to output rx phy mask * - * @return int BLE_ERR_SUCCESS or BLE_ERR_INV_HCI_CMD_PARMS + * @return int BLE_ERR_SUCCESS or BLE_ERR_INV_HCI_CMD_PARMS or BLE_ERR_UNSUPPORTED */ int ble_ll_hci_chk_phy_masks(uint8_t *cmdbuf, uint8_t *txphy, uint8_t *rxphy) { - int rc; uint8_t all_phys; uint8_t rx_phys; uint8_t tx_phys; + /* Check for RFU */ + if ((cmdbuf[1] & ~BLE_HCI_LE_PHY_PREF_MASK_ALL) || + (cmdbuf[2] & ~BLE_HCI_LE_PHY_PREF_MASK_ALL)) { + return BLE_ERR_UNSUPPORTED; + } + /* Check for valid values */ all_phys = cmdbuf[0]; tx_phys = cmdbuf[1] & BLE_HCI_LE_PHY_PREF_MASK_ALL; @@ -338,29 +343,34 @@ ble_ll_hci_chk_phy_masks(uint8_t *cmdbuf, uint8_t *txphy, uint8_t *rxphy) if ((!(all_phys & BLE_HCI_LE_PHY_NO_TX_PREF_MASK) && (tx_phys == 0)) || (!(all_phys & BLE_HCI_LE_PHY_NO_RX_PREF_MASK) && (rx_phys == 0))) { - rc = BLE_ERR_INV_HCI_CMD_PARMS; - } else { - /* If phy not supported, wipe its bit */ + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* If phy not supported, return error */ #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - tx_phys &= ~BLE_HCI_LE_PHY_2M_PREF_MASK; - rx_phys &= ~BLE_HCI_LE_PHY_2M_PREF_MASK; + if((tx_phys & BLE_HCI_LE_PHY_2M_PREF_MASK) || + (rx_phys & BLE_HCI_LE_PHY_2M_PREF_MASK)) { + return BLE_ERR_UNSUPPORTED; + } #endif #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - tx_phys &= ~BLE_HCI_LE_PHY_CODED_PREF_MASK; - rx_phys &= ~BLE_HCI_LE_PHY_CODED_PREF_MASK; -#endif - /* Set the default PHY preferences */ - if (all_phys & BLE_HCI_LE_PHY_NO_TX_PREF_MASK) { - tx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL; - } - *txphy = tx_phys; - if (all_phys & BLE_HCI_LE_PHY_NO_RX_PREF_MASK) { - rx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL; - } - *rxphy = rx_phys; - rc = BLE_ERR_SUCCESS; + if ((tx_phys & BLE_HCI_LE_PHY_CODED_PREF_MASK) || + (rx_phys & BLE_HCI_LE_PHY_CODED_PREF_MASK)) { + return BLE_ERR_UNSUPPORTED; } - return rc; +#endif + /* Set the default PHY preferences */ + if (all_phys & BLE_HCI_LE_PHY_NO_TX_PREF_MASK) { + tx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL; + } + *txphy = tx_phys; + + if (all_phys & BLE_HCI_LE_PHY_NO_RX_PREF_MASK) { + rx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL; + } + *rxphy = rx_phys; + + return BLE_ERR_SUCCESS; } /** From 7b5fd321680b08315318deb1aab57fa24029c791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 11 Sep 2018 10:29:24 +0200 Subject: [PATCH 10/25] nimble/ll: Make sure there is no ADI field in AUX SCAN RSP This fixes LL/DDI/ADV/BV-25-C --- nimble/controller/src/ble_ll_adv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index d813c94db..11fc525d9 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1112,14 +1112,18 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, aux->aux_data_offset = aux_data_offset; aux->aux_data_len = 0; aux->payload_len = 0; + aux->ext_hdr = 0; rem_aux_data_len = AUX_DATA_LEN(advsm) - aux_data_offset; chainable = !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE); - /* Flags and ADI */ - aux->ext_hdr = (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT); - hdr_len = BLE_LL_EXT_ADV_HDR_LEN + BLE_LL_EXT_ADV_FLAGS_SIZE + - BLE_LL_EXT_ADV_DATA_INFO_SIZE; + hdr_len = BLE_LL_EXT_ADV_HDR_LEN + BLE_LL_EXT_ADV_FLAGS_SIZE; + + if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) { + /* Flags and ADI */ + aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT); + hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } /* AdvA for 1st PDU in chain (i.e. AUX_ADV_IND or AUX_SCAN_RSP) */ if (aux_data_offset == 0) { From caba91332214cf5dd994daa324949a3e0786c6ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 11 Sep 2018 12:40:04 +0200 Subject: [PATCH 11/25] nimble/ll: Fix own_addr_type when scanning Make sure scansm->own_addr_type is set corretly when scanning is enabling This fixes LL/DDI/SCN/BV-16 --- nimble/controller/src/ble_ll_scan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 13106b12c..f8303f10d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2923,6 +2923,10 @@ ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext) if (scansm->cur_phy == PHY_NOT_CONFIGURED) { scansm->cur_phy = i; + /* Take own_addr_type from the first configured PHY. + * Note: All configured PHYs shall have the same own_addr_type + */ + scansm->own_addr_type = scanphy->own_addr_type; } else { scansm->next_phy = i; } From 0e51e19925b24d773013f3e634ad61bc2e4968aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 11 Sep 2018 14:19:29 +0200 Subject: [PATCH 12/25] nimble/ll: Allow to report ext advertising without aux data This should fix LL/DDI/SCN/BV-19 --- nimble/controller/src/ble_ll_scan.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index f8303f10d..80e4a287d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1781,7 +1781,7 @@ ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK); i += BLE_LL_EXT_ADV_ADVA_SIZE; } else { - if (aux_data->flags & BLE_LL_AUX_HAS_ADDRA) { + if (aux_data && (aux_data->flags & BLE_LL_AUX_HAS_ADDRA)) { /* Have address in aux_data */ memcpy(out_evt->addr, aux_data->addr, 6); out_evt->addr_type = aux_data->addr_type; @@ -2290,11 +2290,6 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, return; } - if (!aux_data) { - BLE_LL_ASSERT(0); - return; - } - evt = ble_ll_scan_init_ext_adv(NULL); if (!evt) { return; @@ -2331,7 +2326,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, } else { evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED); } - } else { + } else if (aux_data) { if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) { evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE); } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) { From b77cefa259523b894d1db1b9edce2d3eeb1fcd5a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 28 Jun 2018 15:01:40 +0200 Subject: [PATCH 13/25] nimble/ll: Rename ble_ll_ext_adv This is structure for ext adv report so rename it accordingly - current name is really confusing when reading code. --- .../include/controller/ble_ll_scan.h | 4 +-- nimble/controller/src/ble_ll_scan.c | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index b4415b790..5dd36d96d 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -234,9 +234,9 @@ int ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, struct ble_ll_scan_sm **sm); /* Called to parse extended advertising*/ -struct ble_ll_ext_adv; +struct ble_ll_ext_adv_report; int ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, - struct ble_ll_ext_adv *parsed_evt); + struct ble_ll_ext_adv_report *parsed_evt); void ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan); #endif diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 80e4a287d..638bab951 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -95,7 +95,7 @@ struct ble_ll_ext_adv_hdr uint8_t hdr[0]; }; -struct ble_ll_ext_adv { +struct ble_ll_ext_adv_report { /* We support one report per event for now */ uint8_t event_meta; /* BLE_HCI_EVCODE_LE_META */ uint8_t event_len; @@ -572,12 +572,12 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static struct ble_ll_ext_adv * -ble_ll_scan_init_ext_adv(struct ble_ll_ext_adv *copy_from) +static struct ble_ll_ext_adv_report * +ble_ll_scan_init_ext_adv_report(struct ble_ll_ext_adv_report *copy_from) { - struct ble_ll_ext_adv *evt; + struct ble_ll_ext_adv_report *evt; - evt = (struct ble_ll_ext_adv *) ble_hci_trans_buf_alloc( + evt = (struct ble_ll_ext_adv_report *) ble_hci_trans_buf_alloc( BLE_HCI_TRANS_BUF_EVT_LO); if (!evt) { return NULL; @@ -612,7 +612,7 @@ ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype, uint8_t adv_data_len, struct os_mbuf *adv_data, uint8_t *inita) { - struct ble_ll_ext_adv *evt; + struct ble_ll_ext_adv_report *evt; if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { return -1; @@ -624,7 +624,7 @@ ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype, return -1; } - evt = ble_ll_scan_init_ext_adv(NULL); + evt = ble_ll_scan_init_ext_adv_report(NULL); if (!evt) { return 0; } @@ -1591,7 +1591,7 @@ ble_ll_ext_scan_parse_aux_ptr(struct ble_ll_scan_sm *scansm, static void ble_ll_ext_scan_parse_adv_info(struct ble_ll_scan_sm *scansm, - struct ble_ll_ext_adv *evt, uint8_t *buf) + struct ble_ll_ext_adv_report *evt, uint8_t *buf) { uint16_t adv_info = get_le16(buf); @@ -1736,7 +1736,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, */ int ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, - struct ble_ll_ext_adv *out_evt) + struct ble_ll_ext_adv_report *out_evt) { uint8_t pdu_len; uint8_t ext_hdr_len; @@ -2281,8 +2281,8 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data; - struct ble_ll_ext_adv *evt; - struct ble_ll_ext_adv *next_evt; + struct ble_ll_ext_adv_report *evt; + struct ble_ll_ext_adv_report *next_evt; int offset; int datalen; @@ -2290,7 +2290,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, return; } - evt = ble_ll_scan_init_ext_adv(NULL); + evt = ble_ll_scan_init_ext_adv_report(NULL); if (!evt) { return; } @@ -2319,7 +2319,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, * If we cannot allocate another HCI event from pool, just mark * data as truncated. */ - next_evt = ble_ll_scan_init_ext_adv(evt); + next_evt = ble_ll_scan_init_ext_adv_report(evt); if (next_evt) { evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE); From bdc102d00643a5907ebb866e9eedf31873ef561d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 28 Jun 2018 16:17:24 +0200 Subject: [PATCH 14/25] nimble/ll: Fix extended advertising reports handling We may run out of buffers for HCI advertising reports if scanning a lot of devices at the same time and/or host does not handle these events fast enough to return buffers to pool. This is handled properly if we need to fragment advertising data and fail to allocate buffer for 2nd or subsequent events (we'll mark data as trimmed in current event), but in case we cannot allocate buffer for 1st event it will just be dropped without marking data as trimmed. As a result, another PDU scanned from the same advertiser may be handled by host as continuation of previous data which results in corrupted reassembled data and there is no way for host to figure this out. This patch changes extended advertising reports handling to make sure data are always marked as trimmed when we run out of event buffers. We now always keep one pre-allocated event in aux_data so we can always send at least one event that will mark data as trimmed. If we cannot allocate 1st event for chain, it will be just dropped which is ok since host will not event know about this chain. --- .../include/controller/ble_ll_scan.h | 2 + nimble/controller/src/ble_ll_scan.c | 104 ++++++++++++++---- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 5dd36d96d..b217cb06f 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -92,6 +92,7 @@ struct ble_ll_scan_params #define BLE_LL_AUX_INCOMPLETE_BIT 0x02 #define BLE_LL_AUX_INCOMPLETE_ERR_BIT 0x04 #define BLE_LL_AUX_HAS_ADDRA 0x08 +#define BLE_LL_AUX_IGNORE_BIT 0x10 #define BLE_LL_CHECK_AUX_FLAG(aux_data, flag) (!!((aux_data)->flags & flag)) @@ -108,6 +109,7 @@ struct ble_ll_aux_data { uint8_t addr[6]; uint8_t addr_type; struct ble_ll_sched_item sch; + struct ble_ll_ext_adv_report *evt; }; struct ble_ll_scan_sm diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 638bab951..c944bb488 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2272,11 +2272,21 @@ void ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan) { if (aux_scan) { + if (aux_scan->evt) { + ble_hci_trans_buf_free((uint8_t *)aux_scan->evt); + } os_memblock_put(&ext_adv_pool, aux_scan); } } -static void +/* + * Send extended advertising report + * + * @return -1 on error (data truncated or other error) + * 0 on success (data status is "completed") + * 1 on success (data status is not "completed") + */ +static int ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { @@ -2285,39 +2295,69 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, struct ble_ll_ext_adv_report *next_evt; int offset; int datalen; + int rc; + bool need_event; if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - return; + return -1; } - evt = ble_ll_scan_init_ext_adv_report(NULL); - if (!evt) { - return; + /* + * We keep one allocated event in aux_data to be able to truncate chain + * properly in case of error. If there is no event in aux_data it means this + * is the first event for this chain. + */ + if (aux_data && aux_data->evt) { + evt = aux_data->evt; + } else { + evt = ble_ll_scan_init_ext_adv_report(NULL); + if (!evt) { + return -1; + } } datalen = ble_ll_scan_parse_ext_hdr(om, hdr, evt); if (datalen < 0) { + /* XXX what should we do here? send some trimmed event? */ ble_hci_trans_buf_free((uint8_t *)evt); - return; + return -1; } offset = 0; do { + need_event = false; next_evt = NULL; evt->adv_data_len = min(BLE_LL_MAX_EVT_LEN - sizeof(*evt), datalen - offset); - os_mbuf_copydata(om, offset, evt->adv_data_len, evt->adv_data); + evt->event_len = (sizeof(*evt) - BLE_HCI_EVENT_HDR_LEN) + + evt->adv_data_len; + evt->rssi = hdr->rxinfo.rssi; + os_mbuf_copydata(om, offset, evt->adv_data_len, evt->adv_data); offset += evt->adv_data_len; + if (offset < datalen) { + /* Need another event for next fragment of this PDU */ + need_event = true; + } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) { + need_event = false; + } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) { + /* Need another event for next PDU in chain */ + need_event = true; + } else { + need_event = false; + } + + /* Assume data status is not "completed" */ + rc = 1; + + if (need_event) { /* - * We need to fragment this PDU as it does not fit in single HCI - * event. Subsequent event will have exactly the same header data. - * If we cannot allocate another HCI event from pool, just mark - * data as truncated. + * We will need another event so let's try to allocate one now. If + * we cannot do this, need to mark event as truncated. */ next_evt = ble_ll_scan_init_ext_adv_report(evt); @@ -2325,25 +2365,30 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE); } else { evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED); + rc = -1; } - } else if (aux_data) { - if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) { - evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE); - } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) { + } else if (aux_data) { + if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) { evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED); + rc = -1; + } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) { + evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE); } + } else { + rc = 0; } - evt->event_len = (sizeof(*evt) - BLE_HCI_EVENT_HDR_LEN) + - evt->adv_data_len; - evt->rssi = hdr->rxinfo.rssi; - ble_ll_hci_event_send((uint8_t *)evt); evt = next_evt; - } while (evt); + } while (offset < datalen && evt); BLE_LL_ASSERT(offset <= datalen); + + /* Store any event left for later use */ + aux_data->evt = evt; + + return rc; } #endif /** @@ -2376,6 +2421,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd int ext_adv_mode = -1; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct ble_ll_aux_data *aux_data; + int rc; #endif /* Set scan response check flag */ @@ -2480,11 +2526,17 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd aux_data = hdr->rxinfo.user_data; + if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_IGNORE_BIT)) { + goto scan_continue; + } + /* Let's see if that packet contains aux ptr*/ if (BLE_MBUF_HDR_WAIT_AUX(hdr)) { if (ble_ll_sched_aux_scan(hdr, scansm, hdr->rxinfo.user_data)) { /* We are here when could not schedule the aux ptr */ hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT; + /* Mark that chain is trimmed */ + aux_data->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT; } if (!BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_CHAIN_BIT)) { @@ -2499,7 +2551,17 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd STATS_INC(ble_ll_stats, aux_chain_cnt); } - ble_ll_hci_send_ext_adv_report(ptype, om, hdr); + rc = ble_ll_hci_send_ext_adv_report(ptype, om, hdr); + if (rc < 0) { + /* + * Data were trimmed so no need to scan this chain anymore. Also + * make sure we do not send any more events for this chain, just in + * case we managed to scan something before events were processed. + */ + ble_ll_sched_rmv_elem(&aux_data->sch); + hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT; + aux_data->flags |= BLE_LL_AUX_IGNORE_BIT; + } ble_ll_scan_switch_phy(scansm); if (BLE_MBUF_HDR_WAIT_AUX(hdr)) { From ae9da5d5d9f748ea62884b52cdfd2f36d7fc6ba5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 14 Sep 2018 11:07:39 +0200 Subject: [PATCH 15/25] nimble/ll: Fix AuxPtr offset calculations Rounds which were cause by changing from usec->ticks->usec made AuxPtr incorrect. --- nimble/controller/src/ble_ll_adv.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 11fc525d9..943d666d7 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -394,9 +394,6 @@ static void ble_ll_adv_put_aux_ptr(struct ble_ll_adv_sm *advsm, uint32_t offset, uint8_t *dptr) { - /* in usecs */ - offset = os_cputime_ticks_to_usecs(offset); - dptr[0] = advsm->adv_secondary_chan; if (offset > 245700) { @@ -468,7 +465,7 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) /* AuxPtr */ if (AUX_CURRENT(advsm)->sch.enqueued) { - offset = AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time; + offset = os_cputime_ticks_to_usecs(AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time); } else { offset = 0; } @@ -547,12 +544,10 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) */ offset = 0; } else if (advsm->rx_ble_hdr) { - offset = advsm->rx_ble_hdr->rem_usecs + - ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + BLE_LL_IFS + 30; - offset = AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime - - os_cputime_usecs_to_ticks(offset); + offset = os_cputime_ticks_to_usecs(AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime); + offset -= (advsm->rx_ble_hdr->rem_usecs + ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + BLE_LL_IFS); } else { - offset = AUX_NEXT(advsm)->start_time - aux->start_time; + offset = os_cputime_ticks_to_usecs(AUX_NEXT(advsm)->start_time - aux->start_time); } ble_ll_adv_put_aux_ptr(advsm, offset, dptr); From b847d4260848ffe35d38c616c53a4954fc0ed0f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 11:48:08 +0200 Subject: [PATCH 16/25] nimble/ll: Fix getting aux_data Last chain element will not contain AuxPtr in the packet but we still have aux_data from previous chains. --- nimble/controller/src/ble_ll_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index c944bb488..f5bbd1142 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1639,7 +1639,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, tmp_aux_data.mode = rxbuf[2] >> 6; ext_hdr_len = rxbuf[2] & 0x3F; - if (ext_hdr_len < BLE_LL_EXT_ADV_AUX_PTR_SIZE) { + if (ext_hdr_len < BLE_LL_EXT_ADV_AUX_PTR_SIZE && !scansm->cur_aux_data) { return -1; } From ca5f3f4ef308b48ae778ee0670b52f582dae9b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:07:52 +0200 Subject: [PATCH 17/25] nimble/ll: Rename did to adi in aux data This value keeps AdvDataInfo (ADI) therefore fix the name --- nimble/controller/include/controller/ble_ll_scan.h | 2 +- nimble/controller/src/ble_ll_scan.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index b217cb06f..12f115d4b 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -103,7 +103,7 @@ struct ble_ll_aux_data { uint8_t mode; uint8_t scanning; uint8_t flags; - uint16_t did; + uint16_t adi; uint32_t offset; uint8_t offset_units; uint8_t addr[6]; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index f5bbd1142..73a28eeb9 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1665,7 +1665,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, } if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { - tmp_aux_data.did = get_le16(ext_hdr + i); + tmp_aux_data.adi = get_le16(ext_hdr + i); i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; } @@ -1682,7 +1682,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, *aux_data = scansm->cur_aux_data; /* TODO Collision; Do smth smart when did does not match */ - if (tmp_aux_data.did != (*aux_data)->did) { + if (tmp_aux_data.adi != (*aux_data)->adi) { STATS_INC(ble_ll_stats, aux_chain_err); (*aux_data)->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT; } @@ -1703,7 +1703,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, scansm->cur_aux_data = NULL; } - (*aux_data)->did = tmp_aux_data.did; + (*aux_data)->adi = tmp_aux_data.adi; (*aux_data)->chan = tmp_aux_data.chan; (*aux_data)->offset = tmp_aux_data.offset; (*aux_data)->mode = tmp_aux_data.mode; From 2170c0f2e137d1a29422db2f1b8ef84bb8f9ee3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:12:14 +0200 Subject: [PATCH 18/25] nimble/ll: Fix tracking adi in the chains Controller maintains auxdata for the whole advertising event. With this patch we make sure that ADI is not overwitten if chains does not have it e.g. in scan response --- nimble/controller/src/ble_ll_scan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 73a28eeb9..8dbb0e9b3 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1628,6 +1628,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, uint8_t ext_hdr_flags; uint8_t *ext_hdr; uint8_t has_addr = 0; + uint8_t has_adi = 0; int i; struct ble_ll_aux_data tmp_aux_data = { 0 }; @@ -1667,6 +1668,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { tmp_aux_data.adi = get_le16(ext_hdr + i); i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + has_adi = 1; } if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { @@ -1703,7 +1705,10 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, scansm->cur_aux_data = NULL; } - (*aux_data)->adi = tmp_aux_data.adi; + if (has_adi) { + (*aux_data)->adi = tmp_aux_data.adi; + } + (*aux_data)->chan = tmp_aux_data.chan; (*aux_data)->offset = tmp_aux_data.offset; (*aux_data)->mode = tmp_aux_data.mode; From 7f7f46aa4a27e337a14ca0e6dd69d8144e45e7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:15:01 +0200 Subject: [PATCH 19/25] nimble/ll: Add correct sid into scan response advertising report --- nimble/controller/src/ble_ll_scan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 8dbb0e9b3..5cfaaa587 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1809,6 +1809,8 @@ ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { ble_ll_ext_scan_parse_adv_info(scansm, out_evt, (ext_hdr + i)); i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } else if (out_evt->evt_type & BLE_HCI_ADV_SCAN_RSP_MASK) { + out_evt->sid = (aux_data->adi >> 12); } /* In this point of time we don't want to care about aux ptr */ From 865c9da8d9315a4290eefffad81bb06d598b0a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:18:25 +0200 Subject: [PATCH 20/25] nimble/ll: Fix event type in the advertising report containing scan rsp According to specification Bluetooth 5, Vol 2, Part E, 7.7.65.13 "When a scan response is received, bits 0-2 and 4 of the event type shall indicate the properties of the original advertising event" --- .../controller/include/controller/ble_ll_scan.h | 1 + nimble/controller/src/ble_ll_scan.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 12f115d4b..2a9ba826e 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -108,6 +108,7 @@ struct ble_ll_aux_data { uint8_t offset_units; uint8_t addr[6]; uint8_t addr_type; + uint8_t evt_type; struct ble_ll_sched_item sch; struct ble_ll_ext_adv_report *evt; }; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 5cfaaa587..fb1218a2f 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1773,6 +1773,10 @@ ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, return -1; } + if (BLE_MBUF_HDR_SCAN_RSP_RCV(ble_hdr)) { + out_evt->evt_type |= BLE_HCI_ADV_SCAN_RSP_MASK; + } + ext_hdr_len = rxbuf[2] & 0x3F; os_mbuf_adj(om, 3); @@ -1842,13 +1846,16 @@ ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr, out_evt->sec_phy = aux_data->aux_phy; out_evt->prim_phy = aux_data->aux_primary_phy; - if (BLE_MBUF_HDR_SCAN_RSP_RCV(ble_hdr)) { - out_evt->evt_type |= BLE_HCI_ADV_SCAN_RSP_MASK; - } - /* Adjust mbuf to contain advertising data only */ os_mbuf_adj(om, i); + /* Let us first keep update event type in aux data. + * Note that in aux chain and aux scan response packets + * we do miss original event type, which we need for advertising report. + */ + aux_data->evt_type |= out_evt->evt_type; + out_evt->evt_type = aux_data->evt_type; + done: return pdu_len - i - 1; } From e978ffbe378a619d1802dac051c18ea7d8b39907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:21:00 +0200 Subject: [PATCH 21/25] nimble/ll: Fix checking ADI in chains Scan response does not have ADI, therefore do not test it then --- nimble/controller/src/ble_ll_scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index fb1218a2f..23daf33a2 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1684,7 +1684,8 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm, *aux_data = scansm->cur_aux_data; /* TODO Collision; Do smth smart when did does not match */ - if (tmp_aux_data.adi != (*aux_data)->adi) { + if (!((*aux_data)->evt_type & (BLE_HCI_ADV_SCAN_MASK)) + && (tmp_aux_data.adi != (*aux_data)->adi)) { STATS_INC(ble_ll_stats, aux_chain_err); (*aux_data)->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT; } From 586bec1d6179e4ddf9e503a069a82ddcaa491135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 12:22:09 +0200 Subject: [PATCH 22/25] nimble/ll: Minor coding style issue --- nimble/controller/src/ble_ll_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 23daf33a2..85762fbb1 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2396,7 +2396,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, struct os_mbuf *om, ble_ll_hci_event_send((uint8_t *)evt); evt = next_evt; - } while (offset < datalen && evt); + } while ((offset < datalen) && evt); BLE_LL_ASSERT(offset <= datalen); From cade58be1abcbb5c6d1693af7a278b19b064acd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 13:35:43 +0200 Subject: [PATCH 23/25] nimble/ll: Allow to set privacy mode when resolving is disabled Bluetooth specification does not require resolving to be enabled when setting privacy mode. Therefore let us remove this limitation. This fixes LL/SEC/ADV/BV-18 --- nimble/controller/src/ble_ll_resolv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index 4f0308d75..cc0dbfc1a 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -485,10 +485,6 @@ ble_ll_resolve_set_priv_mode(uint8_t *cmdbuf) return BLE_ERR_CMD_DISALLOWED; } - if (!ble_ll_resolv_enabled()) { - return BLE_ERR_CMD_DISALLOWED; - } - /* cmdbuf = addr_type(0) | addr(6) | priv_mode(1) */ rl = ble_ll_resolv_list_find(&cmdbuf[1], cmdbuf[0]); if (!rl) { From 388bbfd645d46b1a6c25c7260506117ac9dedcb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 14 Sep 2018 16:03:18 +0200 Subject: [PATCH 24/25] nimble/ll: Remove reduntant parameter in -ble_ll_ctrl_start_enc_send --- nimble/controller/include/controller/ble_ll_ctrl.h | 2 +- nimble/controller/src/ble_ll_conn_hci.c | 2 +- nimble/controller/src/ble_ll_ctrl.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 0b042a2af..90156d51d 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -253,7 +253,7 @@ uint8_t ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, struct ble_ll_conn_params *req); int ble_ll_ctrl_reject_ind_send(struct ble_ll_conn_sm *connsm, uint8_t rej_opcode, uint8_t err); -int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm, uint8_t opcode); +int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm); int ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu); int ble_ll_ctrl_enc_allowed_pdu_tx(struct os_mbuf_pkthdr *pkthdr); int ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 92039e4c4..526bad00d 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1362,7 +1362,7 @@ ble_ll_conn_hci_le_ltk_reply(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen) swap_buf(connsm->enc_data.enc_block.key, cmdbuf + 2, 16); ble_ll_calc_session_key(connsm); - ble_ll_ctrl_start_enc_send(connsm, BLE_LL_CTRL_START_ENC_REQ); + ble_ll_ctrl_start_enc_send(connsm); rc = BLE_ERR_SUCCESS; ltk_key_cmd_complete: diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index b7d28404c..dea90eeb1 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1119,7 +1119,7 @@ ble_ll_ctrl_is_start_enc_rsp(struct os_mbuf *txpdu) } /** - * Called to create and send a LL_START_ENC_REQ or LL_START_ENC_RSP + * Called to create and send a LL_START_ENC_REQ * * @param connsm * @param err @@ -1127,7 +1127,7 @@ ble_ll_ctrl_is_start_enc_rsp(struct os_mbuf *txpdu) * @return int */ int -ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm, uint8_t opcode) +ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm) { int rc; struct os_mbuf *om; @@ -1135,7 +1135,7 @@ ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm, uint8_t opcode) om = os_msys_get_pkthdr(BLE_LL_CTRL_MAX_PDU_LEN, sizeof(struct ble_mbuf_hdr)); if (om) { - om->om_data[0] = opcode; + om->om_data[0] = BLE_LL_CTRL_START_ENC_REQ; ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, 1); rc = 0; } else { From 6a12e35cb6501dba20280e2edefd3c03a60925da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 18 Sep 2018 10:04:11 +0200 Subject: [PATCH 25/25] nimble/ll: Start LL response timer when sending start encrypt Make sure start that we receive start encrypt response withing 40 sec otherwise drop the link --- nimble/controller/src/ble_ll_ctrl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index dea90eeb1..4ae03bb0f 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1137,6 +1137,11 @@ ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm) if (om) { om->om_data[0] = BLE_LL_CTRL_START_ENC_REQ; ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, 1); + + /* Wait for LL_START_ENC_RSP */ + connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_ENCRYPT; + ble_ll_ctrl_start_rsp_timer(connsm); + rc = 0; } else { rc = -1; @@ -1353,11 +1358,12 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) return BLE_ERR_MAX; } + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); + /* If master, we are done. Stop control procedure and sent event to host */ if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { /* We are encrypted */ connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; - ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1) ble_ll_conn_auth_pyld_timer_start(connsm); #endif