Repository: incubator-mynewt-core Updated Branches: refs/heads/develop 4739392c0 -> ec3cc917f
Add LE ping and Authenticated Payload Timeout event Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/3bed228d Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/3bed228d Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/3bed228d Branch: refs/heads/develop Commit: 3bed228d3ec8ec88f0dd09837931eb00f85d2d07 Parents: 4739392 Author: William San Filippo <wi...@runtime.io> Authored: Wed Jun 15 08:28:44 2016 -0700 Committer: William San Filippo <wi...@runtime.io> Committed: Wed Jun 15 11:06:50 2016 -0700 ---------------------------------------------------------------------- .../controller/include/controller/ble_ll_conn.h | 7 ++ .../controller/include/controller/ble_ll_ctrl.h | 2 +- net/nimble/controller/src/ble_ll.c | 4 + net/nimble/controller/src/ble_ll_conn.c | 77 ++++++++++++++ net/nimble/controller/src/ble_ll_conn_hci.c | 106 +++++++++++++++++++ net/nimble/controller/src/ble_ll_conn_priv.h | 15 +++ net/nimble/controller/src/ble_ll_ctrl.c | 44 ++++++-- net/nimble/controller/src/ble_ll_hci.c | 42 +++++++- net/nimble/host/include/host/host_hci.h | 2 + net/nimble/host/src/ble_hs_startup.c | 10 ++ net/nimble/host/src/host_dbg.c | 25 +++++ net/nimble/host/src/host_hci_cmd.c | 15 +++ net/nimble/include/nimble/hci_common.h | 8 +- 13 files changed, 346 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/include/controller/ble_ll_conn.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_conn.h b/net/nimble/controller/include/controller/ble_ll_conn.h index 035ca39..38a3a22 100644 --- a/net/nimble/controller/include/controller/ble_ll_conn.h +++ b/net/nimble/controller/include/controller/ble_ll_conn.h @@ -110,6 +110,7 @@ union ble_ll_conn_sm_flags { uint32_t send_ltk_req:1; uint32_t encrypted:1; uint32_t encrypt_chg_sent:1; + uint32_t le_ping_supp:1; } cfbit; uint32_t conn_flags; } __attribute__((packed)); @@ -178,6 +179,7 @@ struct ble_ll_conn_sm uint16_t completed_pkts; uint16_t comp_id; uint16_t sub_vers_nr; + uint16_t auth_pyld_tmo; /* could be ifdef'd. 10 msec units */ uint32_t access_addr; uint32_t crcinit; /* only low 24 bits used */ @@ -230,6 +232,10 @@ struct ble_ll_conn_sm /* For scheduling connections */ struct ble_ll_sched_item conn_sch; +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + struct os_callout_func auth_pyld_timer; +#endif + /* * XXX: a note on all these structures for control procedures. First off, * all of these need to be ifdef'd to save memory. Another thing to @@ -261,6 +267,7 @@ struct ble_ll_conn_sm #define CONN_F_CONN_REQ_TXD(csm) ((csm)->csmflags.cfbit.conn_req_txd) #define CONN_F_ENCRYPTED(csm) ((csm)->csmflags.cfbit.encrypted) #define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->csmflags.cfbit.encrypt_chg_sent) +#define CONN_F_LE_PING_SUPP(csm) ((csm)->csmflags.cfbit.le_ping_supp) /* Role */ #define CONN_IS_MASTER(csm) (csm->conn_role == BLE_LL_CONN_ROLE_MASTER) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/include/controller/ble_ll_ctrl.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_ctrl.h b/net/nimble/controller/include/controller/ble_ll_ctrl.h index a5cd99b..f652faf 100644 --- a/net/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/net/nimble/controller/include/controller/ble_ll_ctrl.h @@ -32,7 +32,7 @@ #define BLE_LL_CTRL_PROC_VERSION_XCHG (4) #define BLE_LL_CTRL_PROC_TERMINATE (5) #define BLE_LL_CTRL_PROC_CONN_PARAM_REQ (6) -#define BLE_LL_CRTL_PROC_LE_PING (7) +#define BLE_LL_CTRL_PROC_LE_PING (7) #define BLE_LL_CTRL_PROC_DATA_LEN_UPD (8) #define BLE_LL_CTRL_PROC_NUM (9) #define BLE_LL_CTRL_PROC_IDLE (255) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c index 0459ff0..f1b5f6c 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -1167,6 +1167,10 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size) ble_ll_resolv_init(); #endif +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + features |= BLE_LL_FEAT_LE_PING; +#endif + /* Initialize random number generation */ ble_ll_rand_init(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll_conn.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c index 7b69a65..312c26f 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -1265,6 +1265,44 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime) return rc; } +#if (BLE_LL_CFG_FEAT_LE_PING == 1) +/** + * Callback for the Authenticated payload timer. This function is called + * when the authenticated payload timer expires. When the authenticated + * payload timeout expires, we should + * -> Send the authenticated payload timeout event. + * -> Start the LE ping procedure. + * -> Restart the timer. + * + * @param arg + */ +void +ble_ll_conn_auth_pyld_timer_cb(void *arg) +{ + struct ble_ll_conn_sm *connsm; + + connsm = (struct ble_ll_conn_sm *)arg; + ble_ll_auth_pyld_tmo_event_send(connsm); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING); + ble_ll_conn_auth_pyld_timer_start(connsm); +} + +/** + * Start (or restart) the authenticated payload timer + * + * @param connsm + */ +void +ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm) +{ + int32_t tmo; + + /* Timeout in is in 10 msec units */ + tmo = (int32_t)BLE_LL_CONN_AUTH_PYLD_OS_TMO(connsm->auth_pyld_tmo); + os_callout_reset(&connsm->auth_pyld_timer.cf_c, tmo); +} +#endif + /** * Connection supervision timer callback; means that the connection supervision * timeout has been reached and we should perform the appropriate actions. @@ -1434,6 +1472,15 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED; #endif +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + connsm->auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO; + CONN_F_LE_PING_SUPP(connsm) = 1; + os_callout_func_init(&connsm->auth_pyld_timer, + &g_ble_ll_data.ll_evq, + ble_ll_conn_auth_pyld_timer_cb, + connsm); +#endif + /* Add to list of active connections */ SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); } @@ -1513,6 +1560,10 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) /* Stop any control procedures that might be running */ os_callout_stop(&connsm->ctrl_proc_rsp_timer.cf_c); +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + os_callout_stop(&connsm->auth_pyld_timer.cf_c); +#endif + /* Remove from the active connection list */ SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle); @@ -1842,6 +1893,20 @@ ble_ll_conn_event_end(void *arg) connsm->slave_cur_tx_win_usecs = 0; } +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + /* + * If we are encrypted and have passed the authenticated payload timeout + * we need to send an event to tell the host. Unfortunately, I think we + * need one of these per connection and we have to set this timer + * fairly accurately. So we need to another event in the connection. + * This sucks. + * + * The way this works is that whenever the timer expires it just gets reset + * and we send the autheticated payload timeout event. Note that this timer + * should run even when encryption is paused. + */ +#endif + /* Move to next connection event */ if (ble_ll_conn_next_event(connsm)) { ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL); @@ -2410,6 +2475,18 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) goto conn_rx_data_pdu_end; } +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + /* + * Reset authenticated payload timeout if valid MIC. NOTE: we dont + * check the MIC failure bit as that would have terminated the + * connection + */ + if ((connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED) && + CONN_F_LE_PING_SUPP(connsm) && (acl_len != 0)) { + ble_ll_conn_auth_pyld_timer_start(connsm); + } +#endif + /* Update RSSI */ connsm->conn_rssi = hdr->rxinfo.rssi; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll_conn_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_hci.c b/net/nimble/controller/src/ble_ll_conn_hci.c index 08ced85..e1bc978 100644 --- a/net/nimble/controller/src/ble_ll_conn_hci.c +++ b/net/nimble/controller/src/ble_ll_conn_hci.c @@ -298,6 +298,31 @@ ble_ll_conn_num_comp_pkts_event_send(void) } } +#if (BLE_LL_CFG_FEAT_LE_PING == 1) +/** + * Send a authenticated payload timeout event + * + * NOTE: we currently only send this event when we have a reason to send it; + * not when it fails. + * + * @param reason The BLE error code to send as a disconnect reason + */ +void +ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm) +{ + uint8_t *evbuf; + + if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_AUTH_PYLD_TMO)) { + evbuf = os_memblock_get(&g_hci_cmd_pool); + if (evbuf) { + evbuf[0] = BLE_HCI_EVCODE_AUTH_PYLD_TMO; + evbuf[1] = sizeof(uint16_t); + htole16(evbuf + 2, connsm->conn_handle); + ble_ll_hci_event_send(evbuf); + } + } +} +#endif /** * Send a disconnection complete event. @@ -1035,3 +1060,84 @@ ltk_key_cmd_complete: return rc; } #endif + +#if (BLE_LL_CFG_FEAT_LE_PING == 1) +/** + * Read authenticated payload timeout (OGF=3, OCF==0x007B) + * + * @param cmdbuf + * @param rsplen + * + * @return int + */ +int +ble_ll_conn_hci_rd_auth_pyld_tmo(uint8_t *cmdbuf, uint8_t *rsp, uint8_t *rsplen) +{ + int rc; + uint16_t handle; + struct ble_ll_conn_sm *connsm; + + handle = le16toh(cmdbuf); + connsm = ble_ll_conn_find_active_conn(handle); + if (!connsm) { + rc = BLE_ERR_UNK_CONN_ID; + } else { + htole16(rsp + 2, connsm->auth_pyld_tmo); + rc = BLE_ERR_SUCCESS; + } + + htole16(rsp, handle); + *rsplen = BLE_HCI_RD_AUTH_PYLD_TMO_LEN; + return rc; +} + +/** + * Write authenticated payload timeout (OGF=3, OCF=00x7C) + * + * @param cmdbuf + * @param rsplen + * + * @return int + */ +int +ble_ll_conn_hci_wr_auth_pyld_tmo(uint8_t *cmdbuf, uint8_t *rsp, uint8_t *rsplen) +{ + int rc; + uint16_t handle; + uint16_t tmo; + uint32_t min_tmo; + struct ble_ll_conn_sm *connsm; + + rc = BLE_ERR_SUCCESS; + + handle = le16toh(cmdbuf); + connsm = ble_ll_conn_find_active_conn(handle); + if (!connsm) { + rc = BLE_ERR_UNK_CONN_ID; + goto wr_auth_exit; + } + + /* + * The timeout is in units of 10 msecs. We need to make sure that the + * timeout is greater than or equal to connItvl * (1 + slaveLatency) + */ + tmo = le16toh(cmdbuf + 2); + min_tmo = (uint32_t)connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; + min_tmo *= (connsm->slave_latency + 1); + min_tmo /= 10000; + + if (tmo < min_tmo) { + rc = BLE_ERR_INV_HCI_CMD_PARMS; + } else { + connsm->auth_pyld_tmo = tmo; + if (os_callout_queued(&connsm->auth_pyld_timer.cf_c)) { + ble_ll_conn_auth_pyld_timer_start(connsm); + } + } + +wr_auth_exit: + htole16(rsp, handle); + *rsplen = BLE_HCI_WR_AUTH_PYLD_TMO_LEN; + return rc; +} +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll_conn_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h index 7794a6a..c94093e 100644 --- a/net/nimble/controller/src/ble_ll_conn_priv.h +++ b/net/nimble/controller/src/ble_ll_conn_priv.h @@ -51,6 +51,11 @@ /* Offset (in bytes) of advertising address in connect request */ #define BLE_LL_CONN_REQ_ADVA_OFF (BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN) +/* Default authenticated payload timeout (30 seconds; in 10 msecs increments) */ +#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO (3000) +#define BLE_LL_CONN_AUTH_PYLD_OS_TMO(x) \ + ((((uint32_t)(x)) * 10 * OS_TICKS_PER_SEC) / 1000) + /* Global Link Layer connection parameters */ struct ble_ll_conn_global_params { @@ -115,6 +120,7 @@ uint8_t ble_ll_conn_calc_used_chans(uint8_t *chmap); /* HCI */ void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason); +void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm); int ble_ll_conn_hci_disconnect_cmd(uint8_t *cmdbuf); int ble_ll_conn_hci_rd_rem_ver_cmd(uint8_t *cmdbuf); int ble_ll_conn_create(uint8_t *cmdbuf); @@ -135,4 +141,13 @@ int ble_ll_conn_hci_set_data_len(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_conn_hci_le_start_encrypt(uint8_t *cmdbuf); int ble_ll_conn_hci_le_ltk_reply(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t ocf); +int ble_ll_conn_hci_wr_auth_pyld_tmo(uint8_t *cmdbuf, uint8_t *rsp, + uint8_t *rsplen); +int ble_ll_conn_hci_rd_auth_pyld_tmo(uint8_t *cmdbuf, uint8_t *rsp, + uint8_t *rsplen); +#if (BLE_LL_CFG_FEAT_LE_PING == 1) +void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm); +#else +#define ble_ll_conn_auth_pyld_timer_start(x) +#endif #endif /* H_BLE_LL_CONN_PRIV_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll_ctrl.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_ctrl.c b/net/nimble/controller/src/ble_ll_ctrl.c index 73a5ac2..3ba69af 100644 --- a/net/nimble/controller/src/ble_ll_ctrl.c +++ b/net/nimble/controller/src/ble_ll_ctrl.c @@ -137,6 +137,21 @@ ble_ll_ctrl_len_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } /** + * Process a received LL_PING_RSP control pdu. + * + * NOTE: we dont have to reset the callout since this packet will have had a + * valid MIC and that will restart the authenticated payload timer + * + * @param connsm + */ +static void +ble_ll_ctrl_rx_ping_rsp(struct ble_ll_conn_sm *connsm) +{ + /* Stop the control procedure */ + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_LE_PING); +} + +/** * Called when we receive either a connection parameter request or response. * * @param connsm @@ -274,7 +289,6 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) /* Get opcode of unknown LL control frame */ opcode = dptr[0]; - /* XXX: add others here */ /* Convert opcode to control procedure id */ switch (opcode) { case BLE_LL_CTRL_LENGTH_REQ: @@ -290,13 +304,18 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) case BLE_LL_CTRL_CONN_PARM_REQ: ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ; break; + case BLE_LL_CTRL_PING_REQ: + CONN_F_LE_PING_SUPP(connsm) = 0; +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + os_callout_stop(&connsm->auth_pyld_timer.cf_c); +#endif + ctrl_proc = BLE_LL_CTRL_PROC_LE_PING; + break; default: ctrl_proc = BLE_LL_CTRL_PROC_NUM; break; } - /* XXX: are there any other events that we need to send when we get - the unknown response? */ /* If we are running this one currently, stop it */ if (connsm->cur_ctrl_proc == ctrl_proc) { /* Stop the control procedure */ @@ -304,7 +323,6 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) if (ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { ble_ll_hci_ev_conn_update(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } else if (ctrl_proc == BLE_LL_CTRL_PROC_FEATURE_XCHG) { - /* XXX: should only get this if a slave initiated this */ ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } } @@ -679,6 +697,9 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) /* We are encrypted */ connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + ble_ll_conn_auth_pyld_timer_start(connsm); +#endif rc = BLE_ERR_MAX; } else { /* Procedure has completed but slave needs to send START_ENC_RSP */ @@ -1274,6 +1295,9 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) opcode = BLE_LL_CTRL_CONN_PARM_REQ; ble_ll_ctrl_conn_param_pdu_make(connsm, ctrdata, NULL); break; + case BLE_LL_CTRL_PROC_LE_PING: + opcode = BLE_LL_CTRL_PING_REQ; + break; case BLE_LL_CTRL_PROC_DATA_LEN_UPD: opcode = BLE_LL_CTRL_LENGTH_REQ; ble_ll_ctrl_datalen_upd_make(connsm, dptr); @@ -1559,6 +1583,9 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) case BLE_LL_CTRL_PAUSE_ENC_REQ: feature = BLE_LL_FEAT_LE_ENCRYPTION; break; + case BLE_LL_CTRL_PING_REQ: + feature = BLE_LL_FEAT_LE_PING; + break; default: feature = 0; break; @@ -1670,8 +1697,10 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) break; #endif case BLE_LL_CTRL_PING_REQ: - /* XXX: implement */ - rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP; + rsp_opcode = BLE_LL_CTRL_PING_RSP; + break; + case BLE_LL_CTRL_PING_RSP: + ble_ll_ctrl_rx_ping_rsp(connsm); break; case BLE_LL_CTRL_CONN_PARM_REQ: rsp_opcode = ble_ll_ctrl_rx_conn_param_req(connsm, dptr, rspbuf); @@ -1817,6 +1846,9 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_START_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; + if (CONN_F_LE_PING_SUPP(connsm)) { + ble_ll_conn_auth_pyld_timer_start(connsm); + } } break; case BLE_LL_CTRL_PAUSE_ENC_RSP: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/controller/src/ble_ll_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c index d6e574d..fd75fbb 100644 --- a/net/nimble/controller/src/ble_ll_hci.c +++ b/net/nimble/controller/src/ble_ll_hci.c @@ -36,6 +36,7 @@ /* LE event mask */ static uint8_t g_ble_ll_hci_le_event_mask[BLE_HCI_SET_LE_EVENT_MASK_LEN]; static uint8_t g_ble_ll_hci_event_mask[BLE_HCI_SET_EVENT_MASK_LEN]; +static uint8_t g_ble_ll_hci_event_mask2[BLE_HCI_SET_EVENT_MASK_LEN]; /** * ll hci get num cmd pkts @@ -437,7 +438,11 @@ ble_ll_hci_is_le_event_enabled(int subev) /** * Checks to see if an event has been disabled by the host. * - * @param evcode This is the event code for the event (0 - 63). + * NOTE: there are two "pages" of event masks; the first page is for event + * codes between 0 and 63 and the second page is for event codes 64 and + * greater. + * + * @param evcode This is the event code for the event. * * @return uint8_t 0: event is not enabled; otherwise event is enabled. */ @@ -447,12 +452,20 @@ ble_ll_hci_is_event_enabled(int evcode) uint8_t enabled; uint8_t bytenum; uint8_t bitmask; + uint8_t *evptr; int bitpos; - bitpos = evcode - 1; + if (evcode >= 64) { + evptr = &g_ble_ll_hci_event_mask2[0]; + bitpos = evcode - 64; + } else { + evptr = &g_ble_ll_hci_event_mask[0]; + bitpos = evcode - 1; + } + bytenum = bitpos / 8; bitmask = 1 << (bitpos & 0x7); - enabled = g_ble_ll_hci_event_mask[bytenum] & bitmask; + enabled = evptr[bytenum] & bitmask; return enabled; } @@ -746,6 +759,9 @@ ble_ll_hci_ctlr_bb_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) { int rc; uint8_t len; +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + uint8_t *rspbuf; +#endif /* Assume error; if all pass rc gets set to 0 */ rc = BLE_ERR_INV_HCI_CMD_PARMS; @@ -755,6 +771,9 @@ ble_ll_hci_ctlr_bb_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) /* Move past HCI command header */ cmdbuf += BLE_HCI_CMD_HDR_LEN; +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN; +#endif switch (ocf) { case BLE_HCI_OCF_CB_SET_EVENT_MASK: @@ -768,6 +787,20 @@ ble_ll_hci_ctlr_bb_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) rc = ble_ll_reset(); } break; + case BLE_HCI_OCF_CB_SET_EVENT_MASK2: + if (len == BLE_HCI_SET_EVENT_MASK_LEN) { + memcpy(g_ble_ll_hci_event_mask2, cmdbuf, len); + rc = BLE_ERR_SUCCESS; + } + break; +#if (BLE_LL_CFG_FEAT_LE_PING == 1) + case BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO: + rc = ble_ll_conn_hci_wr_auth_pyld_tmo(cmdbuf, rspbuf, rsplen); + break; + case BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO: + rc = ble_ll_conn_hci_wr_auth_pyld_tmo(cmdbuf, rspbuf, rsplen); + break; +#endif default: rc = BLE_ERR_UNKNOWN_HCI_CMD; break; @@ -1000,4 +1033,7 @@ ble_ll_hci_init(void) g_ble_ll_hci_event_mask[3] = 0xff; g_ble_ll_hci_event_mask[4] = 0xff; g_ble_ll_hci_event_mask[5] = 0x1f; + + /* Set page 2 to 0 */ + memset(g_ble_ll_hci_event_mask2, 0, BLE_HCI_SET_EVENT_MASK_LEN); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/host/include/host/host_hci.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h index 12da775..af7c2c2 100644 --- a/net/nimble/host/include/host/host_hci.h +++ b/net/nimble/host/include/host/host_hci.h @@ -32,6 +32,8 @@ int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata); int host_hci_cmd_send_buf(void *cmddata); void host_hci_cmd_build_set_event_mask(uint64_t event_mask, uint8_t *dst, int dst_len); +void host_hci_cmd_build_set_event_mask2(uint64_t event_mask, uint8_t *dst, + int dst_len); void host_hci_cmd_build_disconnect(uint16_t handle, uint8_t reason, uint8_t *dst, int dst_len); int host_hci_cmd_disconnect(uint16_t handle, uint8_t reason); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/host/src/ble_hs_startup.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_startup.c b/net/nimble/host/src/ble_hs_startup.c index 310c5b8..16834ec 100644 --- a/net/nimble/host/src/ble_hs_startup.c +++ b/net/nimble/host/src/ble_hs_startup.c @@ -157,6 +157,16 @@ ble_hs_startup_set_evmask_tx(void) return rc; } + /** + * Enable the following events: + * 0x0000000000800000 Authenticated Payload Timeout Event + */ + host_hci_cmd_build_set_event_mask2(0x0000000000800000, buf, sizeof buf); + rc = ble_hci_cmd_tx_empty_ack(buf); + if (rc != 0) { + return rc; + } + return 0; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/host/src/host_dbg.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_dbg.c b/net/nimble/host/src/host_dbg.c index d7a31e3..6b58624 100644 --- a/net/nimble/host/src/host_dbg.c +++ b/net/nimble/host/src/host_dbg.c @@ -275,6 +275,28 @@ host_hci_dbg_num_comp_pkts_disp(uint8_t *evdata, uint8_t len) } } +/** + * Display the authenticated payload timeout event + * + * @param evdata + * @param len + */ +static void +host_hci_dbg_auth_pyld_tmo_disp(uint8_t *evdata, uint8_t len) +{ + uint16_t handle; + + if (len != sizeof(uint16_t)) { + BLE_HS_LOG(DEBUG, "ERR: AuthPyldTmoEvent bad length %u\n", len); + return; + + } + + handle = le16toh(evdata); + BLE_HS_LOG(DEBUG, "AuthPyldTmo: handle=%u\n", handle); +} + + static void host_hci_dbg_cmd_comp_info_params(uint8_t status, uint8_t ocf, uint8_t *evdata) { @@ -471,6 +493,9 @@ host_hci_dbg_event_disp(uint8_t *evbuf) case BLE_HCI_EVCODE_LE_META: host_hci_dbg_le_event_disp(evdata[0], len, evdata + 1); break; + case BLE_HCI_EVCODE_AUTH_PYLD_TMO: + host_hci_dbg_auth_pyld_tmo_disp(evdata, len); + break; default: BLE_HS_LOG(DEBUG, "Unknown event 0x%x len=%u\n", evcode, len); break; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/host/src/host_hci_cmd.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c index 887ddfb..09c6944 100644 --- a/net/nimble/host/src/host_hci_cmd.c +++ b/net/nimble/host/src/host_hci_cmd.c @@ -323,6 +323,21 @@ host_hci_cmd_build_set_event_mask(uint64_t event_mask, host_hci_cmd_body_set_event_mask(event_mask, dst); } +void +host_hci_cmd_build_set_event_mask2(uint64_t event_mask, + uint8_t *dst, int dst_len) +{ + BLE_HS_DBG_ASSERT( + dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN); + + host_hci_write_hdr(BLE_HCI_OGF_CTLR_BASEBAND, + BLE_HCI_OCF_CB_SET_EVENT_MASK2, + BLE_HCI_SET_EVENT_MASK_LEN, dst); + dst += BLE_HCI_CMD_HDR_LEN; + + host_hci_cmd_body_set_event_mask(event_mask, dst); +} + static void host_hci_cmd_body_disconnect(uint16_t handle, uint8_t reason, uint8_t *dst) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3bed228d/net/nimble/include/nimble/hci_common.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h index 962df49..0292be5 100644 --- a/net/nimble/include/nimble/hci_common.h +++ b/net/nimble/include/nimble/hci_common.h @@ -61,8 +61,10 @@ /* List of OCF for Controller and Baseband commands (OGF=0x03) */ #define BLE_HCI_OCF_CB_SET_EVENT_MASK (0x0001) #define BLE_HCI_OCF_CB_RESET (0x0003) -#define BLE_HCI_OCF_CB_SET_EV_FILT (0x0005) #define BLE_HCI_OCF_CB_READ_TX_PWR (0x002D) +#define BLE_HCI_OCF_CB_SET_EVENT_MASK2 (0x0063) +#define BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO (0x007B) +#define BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO (0x007C) /* List of OCF for Info Param commands (OGF=0x04) */ #define BLE_HCI_OCF_IP_RD_LOCAL_VER (0x0001) @@ -129,6 +131,10 @@ /* --- Set event mask (OGF 0x03, OCF 0x0001 --- */ #define BLE_HCI_SET_EVENT_MASK_LEN (8) +/* --- Read/Write authenticated payload timeout (ocf 0x007B/0x007C) */ +#define BLE_HCI_RD_AUTH_PYLD_TMO_LEN (4) +#define BLE_HCI_WR_AUTH_PYLD_TMO_LEN (2) + /* --- Read local version information (OGF 0x04, OCF 0x0001) --- */ /* NOTE: does not include status field in command complete event! */ #define BLE_HCI_RD_LOC_VER_INFO_RSPLEN (8)