You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2016/01/27 19:14:39 UTC
incubator-mynewt-larva git commit: First cut at connection parameter
request procedure. Major modifications to scheduling code to fix some
schedule bugs
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 <wi...@micosa.io>
Authored: Wed Jan 27 10:14:23 2016 -0800
Committer: wes3 <wi...@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) {