Repository: incubator-mynewt-larva Updated Branches: refs/heads/master 0e324d9e2 -> d61dbe829
First cut at connection parameter request procedure. Major modifications to scheduling code to fix some schedule bugs Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/d61dbe82 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/d61dbe82 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/d61dbe82 Branch: refs/heads/master Commit: d61dbe829f07da74cddb39f7be27a445969a936b Parents: 0e324d9 Author: wes3 <w...@micosa.io> Authored: Wed Jan 27 10:14:23 2016 -0800 Committer: wes3 <w...@micosa.io> Committed: Wed Jan 27 10:14:30 2016 -0800 ---------------------------------------------------------------------- .../controller/include/controller/ble_ll_conn.h | 3 + net/nimble/controller/src/ble_ll.c | 4 +- net/nimble/controller/src/ble_ll_conn.c | 18 ++- net/nimble/controller/src/ble_ll_conn_hci.c | 12 +- net/nimble/controller/src/ble_ll_conn_priv.h | 4 +- net/nimble/controller/src/ble_ll_ctrl.c | 155 +++++++++++-------- net/nimble/controller/src/ble_ll_hci.c | 7 +- net/nimble/controller/src/ble_ll_hci_ev.c | 10 +- net/nimble/controller/src/ble_ll_sched.c | 105 +++++++------ project/bletest/src/main.c | 56 +++++-- 10 files changed, 224 insertions(+), 150 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 3f4d48f..0076e7d 100644 --- a/net/nimble/controller/include/controller/ble_ll_conn.h +++ b/net/nimble/controller/include/controller/ble_ll_conn.h @@ -183,6 +183,9 @@ struct ble_ll_conn_sm /* For connection update procedure */ struct ble_ll_conn_upd_req conn_update_req; + + /* XXX: for now, just store them all */ + struct ble_ll_conn_params conn_cp; }; /* http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 49435e8..9bab00e 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -50,7 +50,7 @@ /* Configuration for supported features */ #define BLE_LL_CFG_FEAT_DATA_LEN_EXT -#undef BLE_LL_CFG_FEAT_CONN_PARAM_REQ +#define BLE_LL_CFG_FEAT_CONN_PARAM_REQ #undef BLE_LL_CFG_FEAT_LE_ENCRYPTION #undef BLE_LL_CFG_FEAT_EXT_REJECT_IND #define BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG @@ -702,7 +702,7 @@ ble_ll_task(void *arg) case OS_EVENT_T_TIMER: cf = (struct os_callout_func *)ev; assert(cf->cf_func); - cf->cf_func(cf->cf_arg); + cf->cf_func(ev->ev_arg); break; case BLE_LL_EVENT_HCI_CMD: /* Process HCI command */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 e219bbb..8039201 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -102,10 +102,10 @@ extern int ble_hs_rx_data(struct os_mbuf *om); /* Configuration parameters */ #define BLE_LL_CFG_CONN_TX_WIN_SIZE (1) #define BLE_LL_CFG_CONN_TX_WIN_OFF (0) -#define BLE_LL_CFG_CONN_MASTER_SCA (BLE_MASTER_SCA_251_500_PPM << 5) +#define BLE_LL_CFG_CONN_MASTER_SCA (BLE_MASTER_SCA_51_75_PPM << 5) #define BLE_LL_CFG_CONN_MAX_CONNS (32) #define BLE_LL_CFG_CONN_OUR_SCA (60) /* in ppm */ -#define BLE_LL_CFG_CONN_INIT_SLOTS (2) +#define BLE_LL_CFG_CONN_INIT_SLOTS (4) /* We cannot have more than 254 connections given our current implementation */ #if (BLE_LL_CFG_CONN_MAX_CONNS >= 255) @@ -114,8 +114,8 @@ extern int ble_hs_rx_data(struct os_mbuf *om); /* LL configuration definitions */ #define BLE_LL_CFG_SUPP_MAX_RX_BYTES (251) -#define BLE_LL_CFG_SUPP_MAX_TX_BYTES (27) -#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES (27) +#define BLE_LL_CFG_SUPP_MAX_TX_BYTES (251) +#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES (251) /* Sleep clock accuracy table (in ppm) */ static const uint16_t g_ble_sca_ppm_tbl[8] = @@ -992,6 +992,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->comp_id = 0; connsm->sub_vers_nr = 0; connsm->rxd_version_ind = 0; + connsm->reject_reason = BLE_ERR_SUCCESS; /* Reset current control procedure */ connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE; @@ -1268,7 +1269,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Reset the connection supervision timeout */ cputime_timer_stop(&connsm->conn_spvn_timer); - tmo = connsm->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; + tmo = connsm->supervision_tmo; + tmo = tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; + tmo = cputime_usecs_to_ticks(tmo); cputime_timer_start(&connsm->conn_spvn_timer, connsm->anchor_point+tmo); /* Reset update scheduled flag */ @@ -1278,8 +1281,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Calculate data channel index of next connection event */ while (latency > 0) { connsm->last_unmapped_chan = connsm->unmapped_chan; - --latency; connsm->data_chan_index = ble_ll_conn_calc_dci(connsm); + --latency; } /* @@ -1727,6 +1730,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) } } + /* XXX: note: this crashed during interop testing! conn_create_sm=NULL*/ /* Attempt to schedule new connection. Possible that this might fail */ if (!ble_ll_sched_master_new(g_ble_ll_conn_create_sm, ble_hdr->end_cputime, @@ -2131,7 +2135,7 @@ conn_rx_pdu_end: if (connsm->slave_set_last_anchor) { connsm->slave_set_last_anchor = 0; connsm->last_anchor_point = rxhdr->end_cputime - - BLE_TX_DUR_USECS_M(rxpdu->om_data[1]); + cputime_usecs_to_ticks(BLE_TX_DUR_USECS_M(rxpdu->om_data[1])); connsm->anchor_point = connsm->last_anchor_point; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 102462e..29c6810 100644 --- a/net/nimble/controller/src/ble_ll_conn_hci.c +++ b/net/nimble/controller/src/ble_ll_conn_hci.c @@ -467,7 +467,7 @@ ble_ll_conn_read_rem_features(uint8_t *cmdbuf) * @return int */ int -ble_ll_conn_update(uint8_t *cmdbuf) +ble_ll_conn_hci_update(uint8_t *cmdbuf) { int rc; uint8_t ctrl_proc; @@ -493,6 +493,9 @@ ble_ll_conn_update(uint8_t *cmdbuf) /* See if we support this feature */ if ((ble_ll_read_supp_features() & BLE_LL_FEAT_CONN_PARM_REQ) == 0) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + return BLE_ERR_UNSUPP_FEATURE; + } ctrl_proc = BLE_LL_CTRL_PROC_CONN_UPDATE; } else { ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ; @@ -544,7 +547,7 @@ ble_ll_conn_update(uint8_t *cmdbuf) } int -ble_ll_conn_param_reply(uint8_t *cmdbuf, int positive_reply) +ble_ll_conn_hci_param_reply(uint8_t *cmdbuf, int positive_reply) { int rc; uint8_t ble_err; @@ -586,7 +589,8 @@ ble_ll_conn_param_reply(uint8_t *cmdbuf, int positive_reply) om = os_mbuf_get_pkthdr(&g_mbuf_pool, sizeof(struct ble_mbuf_hdr)); if (om) { dptr = om->om_data; - rsp_opcode = ble_ll_ctrl_conn_param_reply(connsm, dptr, NULL); + rsp_opcode = ble_ll_ctrl_conn_param_reply(connsm, dptr, + &connsm->conn_cp); dptr[0] = rsp_opcode; len = g_ble_ll_ctrl_pkt_lengths[rsp_opcode] + 1; ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, len); @@ -621,7 +625,7 @@ ble_ll_conn_create_cancel(void) int rc; struct ble_ll_conn_sm *connsm; - /* WWW: BUG! I send the event before the command complete. Not good. */ + /* XXX: BUG! I send the event before the command complete. Not good. */ /* * If we receive this command and we have not got a connection * create command, we have to return disallowed. The spec does not say http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 e309396..9370f0a 100644 --- a/net/nimble/controller/src/ble_ll_conn_priv.h +++ b/net/nimble/controller/src/ble_ll_conn_priv.h @@ -98,8 +98,8 @@ void ble_ll_disconn_comp_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); -int ble_ll_conn_update(uint8_t *cmdbuf); -int ble_ll_conn_param_reply(uint8_t *cmdbuf, int negative_reply); +int ble_ll_conn_hci_update(uint8_t *cmdbuf); +int ble_ll_conn_hci_param_reply(uint8_t *cmdbuf, int negative_reply); int ble_ll_conn_create_cancel(void); void ble_ll_conn_num_comp_pkts_event_send(void); void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 2eb072e..1e8ba74 100644 --- a/net/nimble/controller/src/ble_ll_ctrl.c +++ b/net/nimble/controller/src/ble_ll_ctrl.c @@ -139,6 +139,16 @@ ble_ll_ctrl_len_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr) return rc; } +/** + * Called when we receive either a connection parameter request or response. + * + * @param connsm + * @param dptr + * @param rspbuf + * @param opcode + * + * @return int + */ static int ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspbuf, uint8_t opcode) @@ -147,30 +157,30 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, int indicate; uint8_t rsp_opcode; uint8_t ble_err; - struct ble_ll_conn_params cp; struct ble_ll_conn_params *req; struct hci_conn_update *hcu; /* Extract parameters and check if valid */ - cp.interval_min = le16toh(dptr); - cp.interval_max = le16toh(dptr + 2); - cp.latency = le16toh(dptr + 4); - cp.timeout = le16toh(dptr + 6); - cp.pref_periodicity = dptr[8]; - cp.ref_conn_event_cnt = le16toh(dptr + 9); - cp.offset0 = le16toh(dptr + 11); - cp.offset1 = le16toh(dptr + 13); - cp.offset2 = le16toh(dptr + 15); - cp.offset3 = le16toh(dptr + 17); - cp.offset4 = le16toh(dptr + 19); - cp.offset5 = le16toh(dptr + 21); + req = &connsm->conn_cp; + req->interval_min = le16toh(dptr); + req->interval_max = le16toh(dptr + 2); + req->latency = le16toh(dptr + 4); + req->timeout = le16toh(dptr + 6); + req->pref_periodicity = dptr[8]; + req->ref_conn_event_cnt = le16toh(dptr + 9); + req->offset0 = le16toh(dptr + 11); + req->offset1 = le16toh(dptr + 13); + req->offset2 = le16toh(dptr + 15); + req->offset3 = le16toh(dptr + 17); + req->offset4 = le16toh(dptr + 19); + req->offset5 = le16toh(dptr + 21); /* Check if parameters are valid */ ble_err = BLE_ERR_SUCCESS; - rc = ble_ll_conn_hci_chk_conn_params(cp.interval_min, - cp.interval_max, - cp.latency, - cp.timeout); + rc = ble_ll_conn_hci_chk_conn_params(req->interval_min, + req->interval_max, + req->latency, + req->timeout); if (rc) { ble_err = BLE_ERR_INV_LMP_LL_PARM; goto conn_param_pdu_exit; @@ -182,20 +192,15 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * not have to notify the host. * XXX: what if we dont like the parameters? When do we check that out? */ - req = NULL; indicate = 1; - if ((connsm->conn_itvl >= cp.interval_min) && - (connsm->conn_itvl <= cp.interval_max) && - (connsm->supervision_tmo == cp.timeout) && - (connsm->slave_latency == cp.latency)) { - indicate = 0; - /* XXX: For now, if we are a master, we wont send a response that - * needs to remember the request. That might change with connection - update pdu. Not sure. */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - req = &cp; + if (opcode == BLE_LL_CTRL_CONN_PARM_REQ) { + if ((connsm->conn_itvl >= req->interval_min) && + (connsm->conn_itvl <= req->interval_max) && + (connsm->supervision_tmo == req->timeout) && + (connsm->slave_latency == req->latency)) { + indicate = 0; + goto conn_parm_req_do_indicate; } - goto conn_parm_req_do_indicate; } /* @@ -216,12 +221,12 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, */ hcu = &connsm->conn_param_req; if (hcu->handle != 0) { - if (!((cp.interval_min < hcu->conn_itvl_min) || - (cp.interval_min > hcu->conn_itvl_max) || - (cp.interval_max < hcu->conn_itvl_min) || - (cp.interval_max > hcu->conn_itvl_max) || - (cp.latency != hcu->conn_latency) || - (cp.timeout != hcu->supervision_timeout))) { + if (!((req->interval_min < hcu->conn_itvl_min) || + (req->interval_min > hcu->conn_itvl_max) || + (req->interval_max < hcu->conn_itvl_min) || + (req->interval_max > hcu->conn_itvl_max) || + (req->latency != hcu->conn_latency) || + (req->timeout != hcu->supervision_timeout))) { indicate = 0; } } @@ -237,7 +242,8 @@ conn_parm_req_do_indicate: * Send event to host. At this point we leave and wait to get * an answer. */ - ble_ll_hci_ev_rem_conn_parm_req(connsm, &cp); + /* XXX: what about masked out event? */ + ble_ll_hci_ev_rem_conn_parm_req(connsm, req); connsm->host_reply_opcode = opcode; connsm->awaiting_host_reply = 1; rsp_opcode = 255; @@ -336,10 +342,9 @@ static void ble_ll_ctrl_conn_param_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, struct ble_ll_conn_params *req) { - uint16_t invalid_offset; + uint16_t offset; struct hci_conn_update *hcu; - invalid_offset = 0xFFFF; /* If we were passed in a request, we use the parameters from the request */ if (req) { htole16(dptr, req->interval_min); @@ -368,12 +373,13 @@ ble_ll_ctrl_conn_param_pdu_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, htole16(dptr + 9, connsm->event_cntr); /* XXX: For now, dont use offsets */ - htole16(dptr + 11, invalid_offset); - htole16(dptr + 13, invalid_offset); - htole16(dptr + 15, invalid_offset); - htole16(dptr + 17, invalid_offset); - htole16(dptr + 19, invalid_offset); - htole16(dptr + 21, invalid_offset); + offset = 0xFFFF; + htole16(dptr + 11, offset); + htole16(dptr + 13, offset); + htole16(dptr + 15, offset); + htole16(dptr + 17, offset); + htole16(dptr + 19, offset); + htole16(dptr + 21, offset); } static void @@ -397,16 +403,17 @@ ble_ll_ctrl_version_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) * @param rsp */ static void -ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) +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; - /* Make sure we have the parameters! */ - assert(connsm->conn_param_req.handle != 0); - - /* * Set instant. We set the instant to the current event counter plus * the amount of slave latency as the slave may not be listening @@ -423,11 +430,41 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) /* Copy parameters in connection update structure */ hcu = &connsm->conn_param_req; req = &connsm->conn_update_req; - req->winsize = connsm->tx_win_size; - req->winoffset = 0; - req->interval = hcu->conn_itvl_max; - req->timeout = hcu->supervision_timeout; - req->latency = hcu->conn_latency; + 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. */ @@ -464,7 +501,7 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, rsp_opcode = BLE_LL_CTRL_CONN_PARM_RSP; } else { /* Create a connection update pdu */ - ble_ll_ctrl_conn_upd_make(connsm, rsp + 1); + ble_ll_ctrl_conn_upd_make(connsm, rsp + 1, req); rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_REQ; } @@ -493,12 +530,6 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return BLE_ERR_MAX; } -#if 0 - /* Deal with receiving this when in this state. I think we are done */ - if (IS_PENDING_CTRL_PROC_M(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) { - } -#endif - /* Retrieve parameters */ reqdata = &connsm->conn_update_req; reqdata->winsize = dptr[0]; @@ -727,7 +758,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) switch (ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_UPDATE: opcode = BLE_LL_CTRL_CONN_UPDATE_REQ; - ble_ll_ctrl_conn_upd_make(connsm, dptr + 1); + ble_ll_ctrl_conn_upd_make(connsm, dptr + 1, NULL); break; case BLE_LL_CTRL_PROC_FEATURE_XCHG: if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/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 3fb1127..fd79d6f 100644 --- a/net/nimble/controller/src/ble_ll_hci.c +++ b/net/nimble/controller/src/ble_ll_hci.c @@ -357,7 +357,7 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) break; case BLE_HCI_OCF_LE_CONN_UPDATE: if (len == BLE_HCI_CONN_UPDATE_LEN) { - rc = ble_ll_conn_update(cmdbuf); + rc = ble_ll_conn_hci_update(cmdbuf); } /* This is a hack; command status gets sent instead of cmd complete */ rc += (BLE_ERR_MAX + 1); @@ -374,13 +374,13 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) case BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR: if (len == BLE_HCI_CONN_PARAM_NEG_REPLY_LEN) { - rc = ble_ll_conn_param_reply(cmdbuf, 0); + rc = ble_ll_conn_hci_param_reply(cmdbuf, 0); } break; case BLE_HCI_OCF_LE_REM_CONN_PARAM_RR: if (len == BLE_HCI_CONN_PARAM_REPLY_LEN) { - rc = ble_ll_conn_param_reply(cmdbuf, 1); + rc = ble_ll_conn_hci_param_reply(cmdbuf, 1); } break; @@ -518,7 +518,6 @@ ble_ll_hci_info_params_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) return rc; } - void ble_ll_hci_cmd_proc(struct os_event *ev) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_hci_ev.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci_ev.c b/net/nimble/controller/src/ble_ll_hci_ev.c index 7bebc5f..500525f 100644 --- a/net/nimble/controller/src/ble_ll_hci_ev.c +++ b/net/nimble/controller/src/ble_ll_hci_ev.c @@ -94,12 +94,10 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status) evbuf[1] = BLE_HCI_LE_CONN_UPD_LEN; evbuf[2] = BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE; evbuf[3] = status; - if (status == BLE_ERR_SUCCESS) { - htole16(evbuf + 4, connsm->conn_handle); - htole16(evbuf + 6, connsm->conn_itvl); - htole16(evbuf + 8, connsm->slave_latency); - htole16(evbuf + 10, connsm->supervision_tmo); - } + htole16(evbuf + 4, connsm->conn_handle); + htole16(evbuf + 6, connsm->conn_itvl); + htole16(evbuf + 8, connsm->slave_latency); + htole16(evbuf + 10, connsm->supervision_tmo); ble_ll_hci_event_send(evbuf); } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/net/nimble/controller/src/ble_ll_sched.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c index 9a639f1..6a0e8cb 100644 --- a/net/nimble/controller/src/ble_ll_sched.c +++ b/net/nimble/controller/src/ble_ll_sched.c @@ -50,7 +50,7 @@ TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q; * @param s1 * @param s2 * - * @return int + * @return int 0: dont overlap 1:overlap */ static int ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, @@ -94,6 +94,13 @@ ble_ll_sched_chk_scan_overlap(struct ble_ll_sched_item *scan, ble_ll_event_send(&scansm->scan_sched_ev); TAILQ_REMOVE(&g_ble_ll_sched_q, scan, link); scan->enqueued = 0; + } else { + /* If scheduled item is before the scan item, we need to reinsert */ + if ((int32_t)(sch->end_time - scan->start_time) <= 0) { + TAILQ_REMOVE(&g_ble_ll_sched_q, scan, link); + scan->enqueued = 0; + ble_ll_sched_scan(scan); + } } } @@ -326,21 +333,13 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend, } else { cputime_timer_stop(&g_ble_ll_sched_timer); TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* Ignore scan/initiate types */ - if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) { - scan = entry; - continue; - } - - /* Set these because the overlap function needs them to be set */ + /* Set these because overlap function needs them to be set */ sch->start_time = earliest_start; sch->end_time = earliest_end; - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - /* Earliest start is end of this event since we overlap */ - earliest_start = entry->end_time; - earliest_end = earliest_start + dur; + /* Ignore scan/initiate types */ + if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) { + scan = entry; } else { /* We can insert if before entry in list */ if ((int32_t)(sch->end_time - entry->start_time) < 0) { @@ -350,6 +349,13 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend, } break; } + + /* Check for overlapping events */ + if (ble_ll_sched_is_overlap(sch, entry)) { + /* Earliest start is end of this event since we overlap */ + earliest_start = entry->end_time; + earliest_end = earliest_start + dur; + } } } @@ -386,6 +392,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend, */ if (scan) { ble_ll_sched_chk_scan_overlap(scan, sch); + sch = TAILQ_FIRST(&g_ble_ll_sched_q); } } @@ -434,22 +441,23 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) cputime_timer_stop(&g_ble_ll_sched_timer); while (1) { /* Skip scanning schedule items */ + next_sch = entry->link.tqe_next; if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) { scan = entry; - continue; - } - - next_sch = entry->link.tqe_next; - if (ble_ll_sched_is_overlap(sch, entry)) { - if (ble_ll_sched_conn_overlap(entry)) { - break; - } } else { + /* Insert if event ends before next starts */ if ((int32_t)(sch->end_time - entry->start_time) < 0) { rc = 0; TAILQ_INSERT_BEFORE(entry, sch, link); break; } + + if (ble_ll_sched_is_overlap(sch, entry)) { + /* If we overlap with a connection, we re-schedule */ + if (ble_ll_sched_conn_overlap(entry)) { + break; + } + } } /* Move to next entry */ @@ -519,14 +527,6 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch) /* Ignore scan/initiate types */ if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) { scan = entry; - continue; - } - - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - /* Earliest start is end of this event since we overlap */ - sch->start_time = entry->end_time; - sch->end_time = sch->start_time + duration; } else { /* We can insert if before entry in list */ if ((int32_t)(sch->end_time - entry->start_time) < 0) { @@ -534,6 +534,13 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch) TAILQ_INSERT_BEFORE(entry, sch, link); break; } + + /* Check for overlapping events */ + if (ble_ll_sched_is_overlap(sch, entry)) { + /* Earliest start is end of this event since we overlap */ + sch->start_time = entry->end_time; + sch->end_time = sch->start_time + duration; + } } } @@ -558,6 +565,12 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch) OS_EXIT_CRITICAL(sr); + /* XXX: some things to test. I am not sure that if we are passed the + output compare that we actually get the interrupt. */ + /* XXX: I am not sure that if we receive a packet while scanning + * that we actually go back to scanning. I need to make sure + we re-enable the receive. Put an event in the log! */ + cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); return rc; @@ -572,6 +585,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch) struct ble_ll_sched_item *next_sch; struct ble_ll_sched_item *scan; + rc = 0; OS_ENTER_CRITICAL(sr); /* The schedule item must occur after current running item (if any) */ @@ -581,30 +595,27 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch) } entry = ble_ll_sched_insert_if_empty(sch); - if (!entry) { - /* Nothing in schedule. Schedule as soon as possible */ - rc = 0; - } else { + if (entry) { scan = NULL; cputime_timer_stop(&g_ble_ll_sched_timer); while (1) { /* Skip scanning schedule items */ + next_sch = entry->link.tqe_next; if (entry->sched_type == BLE_LL_SCHED_TYPE_SCAN) { scan = entry; - continue; - } - - next_sch = entry->link.tqe_next; - if (ble_ll_sched_is_overlap(sch, entry)) { - if (ble_ll_sched_conn_overlap(entry)) { - assert(0); - } } else { + /* Insert before if adv event is before this event */ if ((int32_t)(sch->end_time - entry->start_time) < 0) { rc = 0; TAILQ_INSERT_BEFORE(entry, sch, link); break; } + + if (ble_ll_sched_is_overlap(sch, entry)) { + if (ble_ll_sched_conn_overlap(entry)) { + assert(0); + } + } } /* Move to next entry */ @@ -642,27 +653,27 @@ ble_ll_sched_scan(struct ble_ll_sched_item *sch) os_sr_t sr; struct ble_ll_sched_item *entry; + /* Assume insert to head */ + insert_head = 1; + OS_ENTER_CRITICAL(sr); entry = ble_ll_sched_insert_if_empty(sch); - if (!entry) { - insert_head = 1; - } else { + if (entry) { TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { /* No need to worry about overlap. */ if ((int32_t)(sch->start_time - entry->start_time) < 0) { TAILQ_INSERT_BEFORE(entry, sch, link); break; } + insert_head = 0; } - insert_head = 0; if (!entry) { TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); } else { - if (sch == TAILQ_FIRST(&g_ble_ll_sched_q)) { + if (insert_head) { cputime_timer_stop(&g_ble_ll_sched_timer); - insert_head = 1; } } sch->enqueued = 1; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/d61dbe82/project/bletest/src/main.c ---------------------------------------------------------------------- diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c index 4658e06..cce96ad 100755 --- a/project/bletest/src/main.c +++ b/project/bletest/src/main.c @@ -66,8 +66,8 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE]; #define BLETEST_ROLE_ADVERTISER (0) #define BLETEST_ROLE_SCANNER (1) #define BLETEST_ROLE_INITIATOR (2) -//#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) -#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) +#define BLETEST_CFG_ROLE (BLETEST_ROLE_INITIATOR) +//#define BLETEST_CFG_ROLE (BLETEST_ROLE_ADVERTISER) #define BLETEST_CFG_FILT_DUP_ADV (0) #define BLETEST_CFG_ADV_ITVL (60000 / BLE_HCI_ADV_ITVL) #define BLETEST_CFG_ADV_TYPE BLE_HCI_ADV_TYPE_ADV_IND @@ -96,6 +96,8 @@ struct os_callout_func g_bletest_timer; struct os_task bletest_task; sec_bss_nz_core os_stack_t bletest_stack[BLETEST_STACK_SIZE]; uint32_t g_bletest_conn_end; +int g_bletest_start_update; +uint32_t g_bletest_conn_upd_time; uint8_t g_bletest_current_conns; uint8_t g_bletest_cur_peer_addr[BLE_DEV_ADDR_LEN]; uint8_t g_last_handle_used; @@ -130,6 +132,25 @@ bletest_inc_adv_pkt_num(void) } #endif +void +bletest_send_conn_update(uint16_t handle) +{ + int rc; + struct hci_conn_update hcu; + + hcu.conn_latency = 4; + hcu.supervision_timeout = 2000; + hcu.conn_itvl_min = 1000; + hcu.conn_itvl_max = 1000; + hcu.handle = handle; + hcu.min_ce_len = 4; + hcu.max_ce_len = 4; + + rc = host_hci_cmd_le_conn_update(&hcu); + assert(rc == 0); + host_hci_outstanding_opcode = 0; +} + /** * Sets the advertising data to be sent in advertising pdu's which contain * advertising data. @@ -329,7 +350,6 @@ bletest_execute(void) { int rc; uint16_t handle; - struct hci_conn_update hcu; /* * Determine if there is an active connection for the current handle @@ -367,21 +387,14 @@ bletest_execute(void) g_next_os_time += OS_TICKS_PER_SEC * 5; } else { if (g_next_os_time != 0xffffffff) { +#if 1 if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { - hcu.conn_latency = 4; - hcu.supervision_timeout = 2000; - hcu.conn_itvl_min = 1000; - hcu.conn_itvl_max = 1000; - hcu.handle = 1; - hcu.min_ce_len = 4; - hcu.max_ce_len = 4; - - rc = host_hci_cmd_le_conn_update(&hcu); - assert(rc == 0); - host_hci_outstanding_opcode = 0; - + bletest_send_conn_update(1); g_next_os_time = 0xffffffff; } +#else + g_next_os_time = 0xffffffff; +#endif } } } @@ -505,6 +518,10 @@ bletest_execute(void) host_hci_outstanding_opcode = 0; assert(rc == 0); + /* set conn update time */ + g_bletest_conn_upd_time = os_time_get() + (OS_TICKS_PER_SEC * 5); + g_bletest_start_update = 1; + /* Add to current connections */ ++g_bletest_current_conns; @@ -520,7 +537,14 @@ bletest_execute(void) } } } - +#if 0 + if (g_bletest_start_update) { + if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) { + bletest_send_conn_update(1); + g_bletest_start_update = 0; + } + } +#endif /* See if it is time to hand a data packet to the connection */ if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { if (g_bletest_current_conns) {