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/19 01:14:59 UTC
[2/2] incubator-mynewt-larva git commit: Many changes to the
scheduler and link layer to allow for scheduling of multiple connections.
Also allows concurrent connections and/or advertising and/or scanning and/or
initiating state machines
Many changes to the scheduler and link layer to allow for scheduling of multiple connections. Also allows concurrent connections and/or advertising and/or scanning and/or initiating state machines
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/b6e2b5ff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/b6e2b5ff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/b6e2b5ff
Branch: refs/heads/master
Commit: b6e2b5ffa358ad9696f71d30df4f94466f78ae67
Parents: ccc970c
Author: wes3 <wi...@micosa.io>
Authored: Mon Jan 18 16:14:37 2016 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Mon Jan 18 16:14:50 2016 -0800
----------------------------------------------------------------------
.../controller/include/controller/ble_ll.h | 26 +-
.../controller/include/controller/ble_ll_adv.h | 13 +-
.../controller/include/controller/ble_ll_conn.h | 8 +-
.../controller/include/controller/ble_ll_hci.h | 2 +-
.../controller/include/controller/ble_ll_scan.h | 16 +-
.../include/controller/ble_ll_sched.h | 47 +-
net/nimble/controller/src/ble_ll.c | 125 +--
net/nimble/controller/src/ble_ll_adv.c | 264 ++++---
net/nimble/controller/src/ble_ll_conn.c | 682 +++++++++-------
net/nimble/controller/src/ble_ll_conn_hci.c | 4 +-
net/nimble/controller/src/ble_ll_conn_priv.h | 16 +-
net/nimble/controller/src/ble_ll_ctrl.c | 2 +-
net/nimble/controller/src/ble_ll_scan.c | 386 ++++++----
net/nimble/controller/src/ble_ll_sched.c | 770 ++++++++++++++++---
net/nimble/drivers/native/src/ble_phy.c | 9 +-
net/nimble/drivers/nrf52/src/ble_phy.c | 21 +-
net/nimble/include/nimble/ble.h | 26 +-
project/bletest/src/main.c | 232 +++++-
18 files changed, 1885 insertions(+), 764 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index 6e5b6e1..948d8e6 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -70,6 +70,8 @@ struct ble_ll_stats
uint32_t hci_events_sent;
uint32_t bad_ll_state;
uint32_t bad_acl_hdr;
+ uint32_t sched_state_conn_errs;
+ uint32_t sched_state_adv_errs;
uint32_t rx_bytes;
uint32_t rx_valid_adv_pdus;
uint32_t rx_invalid_adv_pdus;
@@ -108,7 +110,7 @@ extern struct ble_ll_stats g_ble_ll_stats;
#define BLE_LL_EVENT_HCI_CMD (OS_EVENT_T_PERUSER)
#define BLE_LL_EVENT_ADV_EV_DONE (OS_EVENT_T_PERUSER + 1)
#define BLE_LL_EVENT_RX_PKT_IN (OS_EVENT_T_PERUSER + 2)
-#define BLE_LL_EVENT_SCAN_WIN_END (OS_EVENT_T_PERUSER + 3)
+#define BLE_LL_EVENT_SCAN (OS_EVENT_T_PERUSER + 3)
#define BLE_LL_EVENT_CONN_SPVN_TMO (OS_EVENT_T_PERUSER + 4)
#define BLE_LL_EVENT_CONN_EV_END (OS_EVENT_T_PERUSER + 5)
#define BLE_LL_EVENT_TX_PKT_IN (OS_EVENT_T_PERUSER + 6)
@@ -306,7 +308,8 @@ void ble_ll_acl_data_in(struct os_mbuf *txpkt);
int ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan);
/* Called by the PHY when a packet reception ends */
-int ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, uint8_t crcok);
+struct ble_mbuf_hdr;
+int ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr);
/*--- Controller API ---*/
void ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr);
@@ -336,10 +339,14 @@ uint8_t ble_ll_read_supp_features(void);
* XXX: temporary LL debug log. Will get removed once we transition to real
* log
*/
-#undef BLE_LL_LOG
-
-#define BLE_LL_LOG_ID_RX_START (1)
-#define BLE_LL_LOG_ID_RX_END (2)
+#define BLE_LL_LOG
+
+#define BLE_LL_LOG_ID_PHY_SETCHAN (1)
+#define BLE_LL_LOG_ID_RX_START (2)
+#define BLE_LL_LOG_ID_RX_END (3)
+#define BLE_LL_LOG_ID_WFR_EXP (4)
+#define BLE_LL_LOG_ID_PHY_TXEND (5)
+#define BLE_LL_LOG_ID_PHY_DISABLE (9)
#define BLE_LL_LOG_ID_CONN_EV_START (10)
#define BLE_LL_LOG_ID_CONN_TX (15)
#define BLE_LL_LOG_ID_CONN_RX (16)
@@ -347,11 +354,8 @@ uint8_t ble_ll_read_supp_features(void);
#define BLE_LL_LOG_ID_CONN_RX_ACK (18)
#define BLE_LL_LOG_ID_CONN_EV_END (20)
#define BLE_LL_LOG_ID_CONN_END (30)
-#define BLE_LL_LOG_ID_PHY_SETCHAN (200)
-#define BLE_LL_LOG_ID_PHY_DISABLE (201)
-#define BLE_LL_LOG_ID_PHY_ISR (202)
-#define BLE_LL_LOG_ID_PHY_RX (220)
-#define BLE_LL_LOG_ID_PHY_TX (221)
+#define BLE_LL_LOG_ID_ADV_TXBEG (50)
+#define BLE_LL_LOG_ID_ADV_TXDONE (60)
#ifdef BLE_LL_LOG
void ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/include/controller/ble_ll_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h
index a01df8c..b3bc298 100644
--- a/net/nimble/controller/include/controller/ble_ll_adv.h
+++ b/net/nimble/controller/include/controller/ble_ll_adv.h
@@ -129,10 +129,10 @@ void ble_ll_adv_init(void);
void ble_ll_adv_reset(void);
/* Called on rx pdu start when in advertising state */
-int ble_ll_adv_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
+int ble_ll_adv_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
/* Called on rx pdu end when in advertising state */
-int ble_ll_adv_rx_pdu_end(uint8_t pdu_type, struct os_mbuf *rxpdu);
+int ble_ll_adv_rx_isr_end(uint8_t pdu_type, struct os_mbuf *rxpdu, int crcok);
/* Processes received packets at the link layer task */
void ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf,
@@ -144,4 +144,13 @@ int ble_ll_adv_can_chg_whitelist(void);
/* Called when a connection request has been received at the link layer */
int ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr);
+/* Called when an advertising event has been scheduled */
+void ble_ll_adv_scheduled(uint32_t sch_start);
+
+/* Called to halt currently running advertising event */
+void ble_ll_adv_halt(void);
+
+/* Called to determine if advertising is enabled */
+uint8_t ble_ll_adv_enabled(void);
+
#endif /* H_BLE_LL_ADV_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 a11e02d..444ee72 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -18,6 +18,8 @@
#define H_BLE_LL_CONN_
#include "os/os.h"
+#include "nimble/ble.h"
+#include "controller/ble_ll_sched.h"
#include "hal/hal_cputime.h"
/* Roles */
@@ -114,11 +116,12 @@ struct ble_ll_conn_sm
uint32_t access_addr;
uint32_t crcinit; /* only low 24 bits used */
uint32_t anchor_point;
- uint32_t last_anchor_point;
+ uint32_t last_anchor_point; /* slave only */
uint32_t ce_end_time; /* cputime at which connection event should end */
uint32_t terminate_timeout;
uint32_t slave_cur_tx_win_usecs;
uint32_t slave_cur_window_widening;
+ uint32_t last_scheduled;
/* address information */
uint8_t own_addr_type;
@@ -148,6 +151,9 @@ struct ble_ll_conn_sm
/* LL control procedure response timer */
struct os_callout_func ctrl_proc_rsp_timer;
+
+ /* For scheduling connections */
+ struct ble_ll_sched_item conn_sch;
};
/*
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/include/controller/ble_ll_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_hci.h b/net/nimble/controller/include/controller/ble_ll_hci.h
index e9d98a2..32a093a 100644
--- a/net/nimble/controller/include/controller/ble_ll_hci.h
+++ b/net/nimble/controller/include/controller/ble_ll_hci.h
@@ -32,7 +32,7 @@
* number of completed packets event to the host. This number is in
* milliseconds.
*/
-#define BLE_LL_CFG_NUM_COMP_PKT_RATE (1000) /* msecs */
+#define BLE_LL_CFG_NUM_COMP_PKT_RATE (2000) /* msecs */
/* Initialize LL HCI */
void ble_ll_hci_init(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/include/controller/ble_ll_scan.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h
index 31c57fe..75542c3 100644
--- a/net/nimble/controller/include/controller/ble_ll_scan.h
+++ b/net/nimble/controller/include/controller/ble_ll_scan.h
@@ -17,6 +17,8 @@
#ifndef H_BLE_LL_SCAN_
#define H_BLE_LL_SCAN_
+#include "controller/ble_ll_sched.h"
+
/*
* Configuration items for the number of duplicate advertisers and the
* number of advertisers from which we have heard a scan response
@@ -77,9 +79,11 @@ struct ble_ll_scan_sm
uint16_t backoff_count;
uint16_t scan_itvl;
uint16_t scan_window;
+ uint32_t last_sched_time;
uint32_t scan_win_start_time;
struct os_mbuf *scan_req_pdu;
- struct os_event scan_win_end_ev;
+ struct os_event scan_sched_ev;
+ struct ble_ll_sched_item scan_sch;
};
/* Scan types */
@@ -96,7 +100,7 @@ int ble_ll_scan_set_enable(uint8_t *cmd);
/*--- Controller Internal API ---*/
/* Process scan window end event */
-void ble_ll_scan_win_end_proc(void *arg);
+void ble_ll_scan_event_proc(void *arg);
/* Initialize the scanner */
void ble_ll_scan_init(void);
@@ -105,10 +109,10 @@ void ble_ll_scan_init(void);
void ble_ll_scan_reset(void);
/* Called when Link Layer starts to receive a PDU and is in scanning state */
-int ble_ll_scan_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
+int ble_ll_scan_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
/* Called when Link Layer has finished receiving a PDU while scanning */
-int ble_ll_scan_rx_pdu_end(struct os_mbuf *rxpdu);
+int ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
/* Process a scan response PDU */
void ble_ll_scan_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
@@ -131,10 +135,10 @@ int ble_ll_scan_initiator_start(struct hci_create_conn *hcc);
struct os_mbuf *ble_ll_scan_get_pdu(void);
/* Stop the scanning state machine */
-void ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm, int conn_created);
+void ble_ll_scan_sm_stop(int chk_disable);
/* Resume scanning */
-void ble_ll_scan_resume(void);
+void ble_ll_scan_chk_resume(void);
/* Called when wait for response timer expires in scanning mode */
void ble_ll_scan_wfr_timer_exp(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/include/controller/ble_ll_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_sched.h b/net/nimble/controller/include/controller/ble_ll_sched.h
index 48914ae..eff9b2f 100644
--- a/net/nimble/controller/include/controller/ble_ll_sched.h
+++ b/net/nimble/controller/include/controller/ble_ll_sched.h
@@ -17,15 +17,16 @@
#ifndef H_BLE_LL_SCHED_
#define H_BLE_LL_SCHED_
+/* Time per BLE scheduler slot */
+#define BLE_LL_SCHED_USECS_PER_SLOT (1250)
+
/* BLE scheduler errors */
#define BLE_LL_SCHED_ERR_OVERLAP (1)
/* Types of scheduler events */
-#define BLE_LL_SCHED_TYPE_ADV (0)
-#define BLE_LL_SCHED_TYPE_SCAN (1)
-#define BLE_LL_SCHED_TYPE_TX (2)
-#define BLE_LL_SCHED_TYPE_RX (3)
-#define BLE_LL_SCHED_TYPE_CONN (4)
+#define BLE_LL_SCHED_TYPE_ADV (1)
+#define BLE_LL_SCHED_TYPE_SCAN (2)
+#define BLE_LL_SCHED_TYPE_CONN (3)
/* Return values for schedule callback. */
#define BLE_LL_SCHED_STATE_RUNNING (0)
@@ -37,28 +38,48 @@ typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch);
struct ble_ll_sched_item
{
- int sched_type;
+ uint8_t sched_type;
+ uint8_t enqueued;
uint32_t start_time;
uint32_t end_time;
- uint32_t next_wakeup;
void *cb_arg;
sched_cb_func sched_cb;
TAILQ_ENTRY(ble_ll_sched_item) link;
};
-/* Add an item to the schedule */
-int ble_ll_sched_add(struct ble_ll_sched_item *sch);
-
-/* Remove item(s) from schedule */
-int ble_ll_sched_rmv(uint8_t sched_type, void *cb_arg);
-
/* Initialize the scheduler */
int ble_ll_sched_init(void);
+/* Remove item(s) from schedule */
+void ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch);
+
/* Get a schedule item */
struct ble_ll_sched_item *ble_ll_sched_get_item(void);
/* Free a schedule item */
void ble_ll_sched_free_item(struct ble_ll_sched_item *sch);
+/* Schedule a new master connection */
+struct ble_ll_conn_sm;
+int ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, uint32_t adv_rxend,
+ uint8_t req_slots);
+
+/* Schedule a new slave connection */
+int ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm);
+
+/* Schedule a new advertising event */
+int ble_ll_sched_adv_new(struct ble_ll_sched_item *sch);
+
+/* Reschedule an advertising event */
+int ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch);
+
+/* Reschedule a connection that had previously been scheduled or that is over */
+int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm * connsm);
+
+/* Schedule a scanning schedule item (start or stop) */
+void ble_ll_sched_scan(struct ble_ll_sched_item *sch);
+
+/* Stop the scheduler */
+void ble_ll_sched_stop(void);
+
#endif /* H_LL_SCHED_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 927d82d..eb44261 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -29,15 +29,6 @@
#include "ble_ll_conn_priv.h"
#include "hal/hal_cputime.h"
-/*
- * XXX: I need to re-think the whoele LL state code and how I deal with it.
- * I dont think I am handling it very well. The LL state should only change
- * at the LL task I think. I am also not sure how to make sure that any packets
- * handled by the LL are handled by the appropriate state. For example, can I
- * get a scan window end and then process packets? When the schedule event for
- * the scan window ends, what do I do to the LL state? Check all this out.
- */
-
/* XXX:
*
* 1) use the sanity task!
@@ -49,6 +40,11 @@
* start of a frame. Need to look at the various states to see if this is the
* right thing to do.
*
+ * 5) Make sure there is no way we can start a wfr timer and then have
+ * whatever event end and not stop the timer. We want to make sure the timer
+ * cant fire off unless we are sure that it will fire off when the device is
+ * in standby state. At least in standby we are sure no erroneous action will
+ * be taken
*/
/* Configuration for supported features */
@@ -259,12 +255,17 @@ ble_ll_is_our_devaddr(uint8_t *addr, int addr_type)
void
ble_ll_wfr_timer_exp(void *arg)
{
- struct ble_ll_obj *lldata;
+ int rx_start;
+ uint8_t lls;
+
+ rx_start = ble_phy_rx_started();
+ lls = g_ble_ll_data.ll_state;
+
+ ble_ll_log(BLE_LL_LOG_ID_WFR_EXP, lls, 0, (uint32_t)rx_start);
/* If we have started a reception, there is nothing to do here */
- if (!ble_phy_rx_started()) {
- lldata = &g_ble_ll_data;
- switch (lldata->ll_state) {
+ if (!rx_start) {
+ switch (lls) {
case BLE_LL_STATE_ADV:
ble_ll_adv_wfr_timer_exp();
break;
@@ -365,6 +366,7 @@ ble_ll_rx_pkt_in(void)
os_sr_t sr;
uint8_t pdu_type;
uint8_t *rxbuf;
+ uint8_t crcok;
struct os_mbuf_pkthdr *pkthdr;
struct ble_mbuf_hdr *ble_hdr;
struct os_mbuf *m;
@@ -383,17 +385,18 @@ ble_ll_rx_pkt_in(void)
/* Count statistics */
rxbuf = m->om_data;
ble_hdr = BLE_MBUF_HDR_PTR(m);
- if (ble_hdr->rxinfo.crcok) {
+ crcok = BLE_MBUF_HDR_CRC_OK(ble_hdr);
+ if (crcok) {
/* The total bytes count the PDU header and PDU payload */
g_ble_ll_stats.rx_bytes += pkthdr->omp_len;
}
if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
- ble_ll_conn_rx_data_pdu(m, ble_hdr->rxinfo.crcok);
+ ble_ll_conn_rx_data_pdu(m, ble_hdr);
} else {
/* Get advertising PDU type */
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
- if (ble_hdr->rxinfo.crcok) {
+ if (crcok) {
/* Count by type only with valid crc */
++g_ble_ll_stats.rx_valid_adv_pdus;
ble_ll_count_rx_adv_pdus(pdu_type);
@@ -402,7 +405,7 @@ ble_ll_rx_pkt_in(void)
}
/* Process the PDU */
- switch (g_ble_ll_data.ll_state) {
+ switch (BLE_MBUF_HDR_RX_STATE(ble_hdr)) {
case BLE_LL_STATE_ADV:
ble_ll_adv_rx_pkt_in(pdu_type, rxbuf, ble_hdr);
break;
@@ -418,6 +421,7 @@ ble_ll_rx_pkt_in(void)
break;
}
+
/* Free the packet buffer */
os_mbuf_free(m);
}
@@ -488,7 +492,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
*/
if (g_ble_ll_data.ll_state == BLE_LL_STATE_CONNECTION) {
/* Call conection pdu rx start function */
- ble_ll_conn_rx_pdu_start();
+ ble_ll_conn_rx_isr_start();
/* Set up to go from rx to tx */
rc = 1;
@@ -504,7 +508,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
switch (g_ble_ll_data.ll_state) {
case BLE_LL_STATE_ADV:
- rc = ble_ll_adv_rx_pdu_start(pdu_type, rxpdu);
+ rc = ble_ll_adv_rx_isr_start(pdu_type, rxpdu);
break;
case BLE_LL_STATE_INITIATING:
if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
@@ -515,7 +519,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
}
break;
case BLE_LL_STATE_SCANNING:
- rc = ble_ll_scan_rx_pdu_start(pdu_type, rxpdu);
+ rc = ble_ll_scan_rx_isr_start(pdu_type, rxpdu);
break;
case BLE_LL_STATE_CONNECTION:
/* Should not occur */
@@ -537,7 +541,8 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
*
* NOTE: Called from interrupt context!
*
- * @param rxbuf
+ * @param rxpdu Pointer to received PDU
+ * ble_hdr Pointer to BLE header of received mbuf
*
* @return int
* < 0: Disable the phy after reception.
@@ -545,18 +550,24 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
* > 0: Do not disable PHY as that has already been done.
*/
int
-ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, uint8_t crcok)
+ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
{
int rc;
int badpkt;
uint8_t pdu_type;
uint8_t len;
+ uint8_t chan;
+ uint8_t crcok;
uint16_t mblen;
uint8_t *rxbuf;
/* Set the rx buffer pointer to the start of the received data */
rxbuf = rxpdu->om_data;
+ /* Get channel and CRC status from BLE header */
+ chan = ble_hdr->rxinfo.channel;
+ crcok = BLE_MBUF_HDR_CRC_OK(ble_hdr);
+
ble_ll_log(BLE_LL_LOG_ID_RX_END,
chan,
((uint16_t)crcok << 8) | rxbuf[1],
@@ -581,14 +592,19 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, uint8_t crcok)
* Data channel pdu. We should be in CONNECTION state with an
* ongoing connection.
*/
- rc = ble_ll_conn_rx_pdu_end(rxpdu, ble_phy_access_addr_get());
+ rc = ble_ll_conn_rx_isr_end(rxpdu, ble_phy_access_addr_get());
return rc;
}
- /* Get advertising PDU type */
+ /* Get advertising PDU type and length */
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
+ /* Setup the mbuf lengths */
+ mblen = len + BLE_LL_PDU_HDR_LEN;
+ OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
+ rxpdu->om_len = mblen;
+
/* If the CRC checks, make sure lengths check! */
if (crcok) {
badpkt = 0;
@@ -621,38 +637,35 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, uint8_t crcok)
if (badpkt) {
++g_ble_ll_stats.rx_adv_malformed_pkts;
os_mbuf_free(rxpdu);
- return -1;
+ rxpdu = NULL;
+ rc = -1;
}
}
- /* Setup the mbuf lengths */
- mblen = len + BLE_LL_PDU_HDR_LEN;
- OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
- rxpdu->om_len = mblen;
/* Hand packet to the appropriate state machine (if crc ok) */
- rc = -1;
- if (crcok) {
- switch (g_ble_ll_data.ll_state) {
- case BLE_LL_STATE_ADV:
- rc = ble_ll_adv_rx_pdu_end(pdu_type, rxpdu);
- break;
- case BLE_LL_STATE_SCANNING:
- rc = ble_ll_scan_rx_pdu_end(rxpdu);
- break;
- case BLE_LL_STATE_INITIATING:
- rc = ble_ll_init_rx_pdu_end(rxpdu);
- break;
- /* Invalid states */
- case BLE_LL_STATE_CONNECTION:
- default:
- assert(0);
- break;
- }
+ switch (BLE_MBUF_HDR_RX_STATE(ble_hdr)) {
+ case BLE_LL_STATE_ADV:
+ rc = ble_ll_adv_rx_isr_end(pdu_type, rxpdu, crcok);
+ break;
+ case BLE_LL_STATE_SCANNING:
+ rc = ble_ll_scan_rx_isr_end(rxpdu, crcok);
+ break;
+ case BLE_LL_STATE_INITIATING:
+ rc = ble_ll_init_rx_isr_end(rxpdu, crcok);
+ break;
+ /* Invalid states */
+ case BLE_LL_STATE_CONNECTION:
+ default:
+ rc = -1;
+ assert(0);
+ break;
}
/* Hand packet up to higher layer (regardless of CRC failure) */
- ble_ll_rx_pdu_in(rxpdu);
+ if (rxpdu) {
+ ble_ll_rx_pdu_in(rxpdu);
+ }
return rc;
}
@@ -668,6 +681,7 @@ void
ble_ll_task(void *arg)
{
struct os_event *ev;
+ struct os_callout_func *cf;
/* Init ble phy */
ble_phy_init();
@@ -681,9 +695,11 @@ ble_ll_task(void *arg)
/* Wait for an event */
while (1) {
ev = os_eventq_get(&g_ble_ll_data.ll_evq);
-
switch (ev->ev_type) {
case OS_EVENT_T_TIMER:
+ cf = (struct os_callout_func *)ev;
+ assert(cf->cf_func);
+ cf->cf_func(cf->cf_arg);
break;
case BLE_LL_EVENT_HCI_CMD:
/* Process HCI command */
@@ -692,8 +708,8 @@ ble_ll_task(void *arg)
case BLE_LL_EVENT_ADV_EV_DONE:
ble_ll_adv_event_done(ev->ev_arg);
break;
- case BLE_LL_EVENT_SCAN_WIN_END:
- ble_ll_scan_win_end_proc(ev->ev_arg);
+ case BLE_LL_EVENT_SCAN:
+ ble_ll_scan_event_proc(ev->ev_arg);
break;
case BLE_LL_EVENT_RX_PKT_IN:
ble_ll_rx_pkt_in();
@@ -821,7 +837,8 @@ ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr)
* layer; it does not perform a HW reset of the controller nor does it reset
* the HCI interface.
*
- *
+ * Context: Link Layer task (HCI command)
+ *
* @return int The ble error code to place in the command complete event that
* is returned when this command is issued.
*/
@@ -829,12 +846,16 @@ int
ble_ll_reset(void)
{
int rc;
+ os_sr_t sr;
/* Stop the phy */
ble_phy_disable();
/* Stop any wait for response timer */
+ OS_ENTER_CRITICAL(sr);
ble_ll_wfr_disable();
+ ble_ll_sched_stop();
+ OS_EXIT_CRITICAL(sr);
/* Stop any scanning */
ble_ll_scan_reset();
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/net/nimble/controller/src/ble_ll_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
index 5302f66..d74b61a 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -46,14 +46,12 @@
* 2) Only public device addresses supported right now.
* 3) How do features get supported? What happens if device does not support
* advertising? (for example)
- * 4) Correct calculation of schedule start and end times for the various
- * scheduled advertising activities.
- * 5) How to determine the advertising interval we will actually use. As of
+ * 4) How to determine the advertising interval we will actually use. As of
* now, we set it to max.
- * 6) Currently, when we set scheduling events, we dont take into account
- * processor overhead/delays. We will want to do that.
- * 7) How does the advertising channel tx power get set? I dont implement
+ * 5) How does the advertising channel tx power get set? I dont implement
* that currently.
+ * 6) The time between transmissions inside an advertising event is set to
+ * max. Need to deal with this.
*/
/*
@@ -89,6 +87,7 @@ struct ble_ll_adv_sm
struct os_mbuf *adv_pdu;
struct os_mbuf *scan_rsp_pdu;
struct os_event adv_txdone_ev;
+ struct ble_ll_sched_item adv_sch;
};
/* The advertising state machine global object */
@@ -149,7 +148,6 @@ ble_ll_adv_first_chan(struct ble_ll_adv_sm *advsm)
return adv_chan;
}
-
/**
* Compares the advertiser address in an advertising PDU (scan request or
* connect request) with our address to see if there is a match
@@ -327,15 +325,24 @@ ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm)
}
/**
- * Scheduler callback when an advertising PDU has been sent.
+ * Called to indicate the advertising event is over.
+ *
+ * Context: Interrupt
+ *
+ * @param advsm
*
- * @param arg
*/
-static int
-ble_ll_adv_tx_done_cb(struct ble_ll_sched_item *sch)
+static void
+ble_ll_adv_tx_done(void *arg)
{
- os_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_adv_sm.adv_txdone_ev);
- return BLE_LL_SCHED_STATE_DONE;
+ struct ble_ll_adv_sm *advsm;
+
+ advsm = (struct ble_ll_adv_sm *)arg;
+ os_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev);
+
+ ble_ll_log(BLE_LL_LOG_ID_ADV_TXDONE, ble_ll_state_get(), 0, 0);
+
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
}
/**
@@ -363,24 +370,25 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
rc = ble_phy_setchan(advsm->adv_chan, 0, 0);
assert(rc == 0);
- /* Set the callbacks */
- ble_phy_set_txend_cb(NULL, NULL);
-
/* Set phy mode based on type of advertisement */
if (advsm->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
end_trans = BLE_PHY_TRANSITION_NONE;
+ ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
} else {
end_trans = BLE_PHY_TRANSITION_TX_RX;
+ ble_phy_set_txend_cb(NULL, NULL);
}
/* This is for debug */
start_time = cputime_get32();
+ /* XXX: transmit using an output compare */
/* Transmit advertisement */
rc = ble_phy_tx(advsm->adv_pdu, BLE_PHY_TRANSITION_NONE, end_trans);
if (rc) {
/* Transmit failed. */
- rc = ble_ll_adv_tx_done_cb(sch);
+ ble_ll_adv_tx_done(advsm);
+ rc = BLE_LL_SCHED_STATE_DONE;
} else {
/* Check if we were late getting here */
if ((int32_t)(start_time - (advsm->adv_pdu_start_time -
@@ -394,68 +402,71 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
/* Count # of adv. sent */
++g_ble_ll_adv_stats.adv_txg;
- /* Set next schedule wakeup time */
- sch->next_wakeup = sch->end_time;
- sch->sched_cb = ble_ll_adv_tx_done_cb;
-
+ /* This schedule item is now running */
rc = BLE_LL_SCHED_STATE_RUNNING;
}
return rc;
}
-static struct ble_ll_sched_item *
-ble_ll_adv_sched_set(struct ble_ll_adv_sm *advsm)
+static void
+ble_ll_adv_set_sched(struct ble_ll_adv_sm *advsm, int sched_new)
{
- int rc;
uint32_t max_usecs;
struct ble_ll_sched_item *sch;
- sch = ble_ll_sched_get_item();
- if (sch) {
- /* Set sched type */
- sch->sched_type = BLE_LL_SCHED_TYPE_ADV;
+ sch = &advsm->adv_sch;
+ sch->cb_arg = advsm;
+ sch->sched_cb = ble_ll_adv_tx_start_cb;
+ sch->sched_type = BLE_LL_SCHED_TYPE_ADV;
- /* XXX: HW output compare to trigger tx start? Look into this */
- /* Set the start time of the event */
- sch->start_time = advsm->adv_pdu_start_time -
- cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
+ /* Set end time to maximum time this schedule item may take */
+ max_usecs = BLE_TX_DUR_USECS_M(advsm->adv_pdu_len);
+ switch (advsm->adv_type) {
+ case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
+ case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
+ max_usecs += BLE_LL_ADV_DIRECT_SCHED_MAX_USECS;
+ break;
+ case BLE_HCI_ADV_TYPE_ADV_IND:
+ case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
+ max_usecs += BLE_LL_ADV_SCHED_MAX_USECS;
+ break;
+ default:
+ break;
+ }
- /* Set the callback and argument */
- sch->cb_arg = advsm;
- sch->sched_cb = ble_ll_adv_tx_start_cb;
-
- /* Set end time to maximum time this schedule item may take */
- max_usecs = BLE_TX_DUR_USECS_M(advsm->adv_pdu_len);
- switch (advsm->adv_type) {
- case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD:
- case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD:
- max_usecs += BLE_LL_ADV_DIRECT_SCHED_MAX_USECS;
- break;
- case BLE_HCI_ADV_TYPE_ADV_IND:
- case BLE_HCI_ADV_TYPE_ADV_SCAN_IND:
- max_usecs += BLE_LL_ADV_SCHED_MAX_USECS;
- break;
- default:
- break;
- }
+ /*
+ * XXX: For now, just schedule some additional time so we insure we have
+ * enough time to do everything we want.
+ */
+ max_usecs += XCVR_PROC_DELAY_USECS;
+ if (sched_new) {
/*
- * We dont really care if this is super accurate; it really is only
- * used to block time in the scheduler.
- */
- sch->end_time = advsm->adv_pdu_start_time +
- cputime_usecs_to_ticks(max_usecs);
-
- /* XXX: for now, we cant get an overlap so assert on error. */
- /* Add the item to the scheduler */
- rc = ble_ll_sched_add(sch);
- assert(rc == 0);
+ * We have to add the scheduling delay and tx start delay to the max
+ * time of the event since the pdu does not start at the scheduled start.
+ */
+ max_usecs += XCVR_TX_SCHED_DELAY_USECS;
+ sch->start_time = cputime_get32();
+ sch->end_time = sch->start_time + cputime_usecs_to_ticks(max_usecs);
} else {
- ++g_ble_ll_adv_stats.cant_set_sched;
+ sch->start_time = advsm->adv_pdu_start_time -
+ cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
+ sch->end_time = advsm->adv_pdu_start_time +
+ cputime_usecs_to_ticks(max_usecs);
}
+}
- return sch;
+/**
+ * Called when advertising need to be halted. This normally should not be called
+ * and is only called when a scheduled item executes but advertising is still
+ * running.
+ *
+ */
+void
+ble_ll_adv_halt(void)
+{
+ ble_ll_adv_tx_done(&g_ble_ll_adv_sm);
}
/**
@@ -575,19 +586,23 @@ ble_ll_adv_set_adv_params(uint8_t *cmd)
static void
ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
{
+ os_sr_t sr;
+
if (advsm->enabled) {
/* Disable whitelisting (just in case) */
ble_ll_whitelist_disable();
/* Remove any scheduled advertising items */
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV, NULL);
+ ble_ll_sched_rmv_elem(&advsm->adv_sch);
os_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev);
/* Set to standby if we are no longer advertising */
+ OS_ENTER_CRITICAL(sr);
if (ble_ll_state_get() == BLE_LL_STATE_ADV) {
ble_ll_wfr_disable();
ble_ll_state_set(BLE_LL_STATE_STANDBY);
}
+ OS_EXIT_CRITICAL(sr);
/* Disable advertising */
advsm->enabled = 0;
@@ -608,9 +623,7 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
static int
ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
{
- int rc;
uint8_t adv_chan;
- struct ble_ll_sched_item *sch;
/*
* XXX: not sure if I should do this or just report whatever random
@@ -661,12 +674,25 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
}
/*
- * Set start time for the advertising event. This time is the same
- * as the time we will send the first PDU. Since there does not seem
- * to be any requirements as to when we start, we do it asap.
- */
- advsm->adv_event_start_time = cputime_get32() +
- cputime_usecs_to_ticks(BLE_LL_IFS + XCVR_PROC_DELAY_USECS);
+ * Schedule advertising. We set the initial schedule start and end
+ * times to the earliest possible start/end.
+ */
+ ble_ll_adv_set_sched(advsm, 1);
+ ble_ll_sched_adv_new(&advsm->adv_sch);
+
+ return BLE_ERR_SUCCESS;
+}
+
+void
+ble_ll_adv_scheduled(uint32_t sch_start)
+{
+ struct ble_ll_adv_sm *advsm;
+
+ advsm = &g_ble_ll_adv_sm;
+
+ /* The event start time is when we start transmission of the adv PDU */
+ advsm->adv_event_start_time = sch_start +
+ cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
advsm->adv_pdu_start_time = advsm->adv_event_start_time;
@@ -677,17 +703,6 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
*/
advsm->adv_dir_hd_end_time = advsm->adv_event_start_time +
cputime_usecs_to_ticks(BLE_LL_ADV_STATE_HD_MAX * 1000);
-
- /* Add to schedule. If we cant, we will just inform host we are too busy */
- rc = BLE_ERR_SUCCESS;
- sch = ble_ll_adv_sched_set(advsm);
- if (!sch) {
- advsm->enabled = 0;
- ble_ll_whitelist_disable();
- rc = BLE_ERR_CTLR_BUSY;
- }
-
- return rc;
}
/**
@@ -707,7 +722,9 @@ ble_ll_adv_read_txpwr(uint8_t *rspbuf, uint8_t *rsplen)
}
/**
- * Turn advertising on/off.
+ * Turn advertising on/off.
+ *
+ * Context: Link Layer task
*
* @param cmd
*
@@ -873,7 +890,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
/* Setup to transmit the scan response if appropriate */
rc = -1;
if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
- /* NOTE: no callback nneds to be set as it should be NULL already */
+ ble_phy_set_txend_cb(ble_ll_adv_tx_done, &g_ble_ll_adv_sm);
rc = ble_phy_tx(advsm->scan_rsp_pdu, BLE_PHY_TRANSITION_RX_TX,
BLE_PHY_TRANSITION_NONE);
if (!rc) {
@@ -964,15 +981,25 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
* > 0: Do not disable PHY as that has already been done.
*/
int
-ble_ll_adv_rx_pdu_end(uint8_t pdu_type, struct os_mbuf *rxpdu)
+ble_ll_adv_rx_isr_end(uint8_t pdu_type, struct os_mbuf *rxpdu, int crcok)
{
int rc;
rc = -1;
- if ((pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) ||
- (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ)) {
- /* Process request */
- rc = ble_ll_adv_rx_req(pdu_type, rxpdu);
+ if (rxpdu == NULL) {
+ ble_ll_adv_tx_done(&g_ble_ll_adv_sm);
+ } else {
+ if (crcok) {
+ if ((pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) ||
+ (pdu_type == BLE_ADV_PDU_TYPE_CONNECT_REQ)) {
+ /* Process request */
+ rc = ble_ll_adv_rx_req(pdu_type, rxpdu);
+ }
+ }
+ }
+
+ if (rc) {
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
}
return rc;
@@ -997,12 +1024,20 @@ ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
int adv_event_over;
/*
- * We should remove the schedule item in all cases except when we
- * are sending a scan response or we have stopped advertising due to
- * receiving a connect request
+ * If we have received a scan request and we are transmitting a response
+ * or we have received a valid connect request, dont "end" the advertising
+ * event. In the case of a connect request we will stop advertising. In
+ * the case of the scan response transmission we will get a transmit
+ * end callback.
+ *
+ * XXX: I dont know why I wait to reschedule after transmitting a scan
+ * response. I wont schedule over it and I can use the transmission time
+ * to schedule the next advertising event. I also get rid of the code to
+ * deal with the "scan response transmitted". All depends on how we
+ * schedule the next transmissions in the advertising event.
*/
adv_event_over = 1;
- if (hdr->rxinfo.crcok) {
+ if (BLE_MBUF_HDR_CRC_OK(hdr)) {
if (ptype == BLE_ADV_PDU_TYPE_CONNECT_REQ) {
if (ble_ll_adv_conn_req_rxd(rxbuf, hdr)) {
adv_event_over = 0;
@@ -1034,7 +1069,7 @@ ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr)
* > 0: Continue to receive frame and go from rx to tx when done
*/
int
-ble_ll_adv_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
+ble_ll_adv_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
{
int rc;
struct ble_ll_adv_sm *advsm;
@@ -1061,6 +1096,14 @@ ble_ll_adv_rx_pdu_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
}
}
+ /*
+ * If we abort the frame, we need to post the LL task to check if the
+ * advertising event is over.
+ */
+ if (rc < 0) {
+ ble_ll_adv_tx_done(advsm);
+ }
+
return rc;
}
@@ -1078,15 +1121,19 @@ ble_ll_adv_event_done(void *arg)
uint8_t final_adv_chan;
int32_t delta_t;
uint32_t itvl;
+ uint32_t start_time;
struct ble_ll_adv_sm *advsm;
/* Stop advertising event */
advsm = (struct ble_ll_adv_sm *)arg;
assert(advsm->enabled);
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV, NULL);
+ /* Check if we need to resume scanning */
+ ble_ll_scan_chk_resume();
+
+ /* Remove the element from the schedule if it is still there. */
+ ble_ll_sched_rmv_elem(&advsm->adv_sch);
os_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev);
- ble_ll_state_set(BLE_LL_STATE_STANDBY);
/* For debug purposes */
#ifdef BLETEST
@@ -1144,7 +1191,10 @@ ble_ll_adv_event_done(void *arg)
* count a statistic and close the current advertising event. We will
* then setup the next advertising event.
*/
- delta_t = (int32_t)(advsm->adv_pdu_start_time - cputime_get32());
+ start_time = advsm->adv_pdu_start_time -
+ cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
+
+ delta_t = (int32_t)(start_time - cputime_get32());
if (delta_t < 0) {
/* Count times we were late */
++g_ble_ll_adv_stats.late_tx_done;
@@ -1179,9 +1229,14 @@ ble_ll_adv_event_done(void *arg)
}
}
- if (!ble_ll_adv_sched_set(advsm)) {
- /* XXX: we will need to set a timer here to wake us up */
- assert(0);
+ ble_ll_adv_set_sched(advsm, 0);
+
+ /*
+ * In the unlikely event we cant reschedule this, just post a done
+ * event and we will reschedule the next advertising event
+ */
+ if (ble_ll_sched_adv_reschedule(&advsm->adv_sch)) {
+ os_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev);
}
}
@@ -1217,7 +1272,7 @@ void
ble_ll_adv_wfr_timer_exp(void)
{
ble_phy_disable();
- os_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_adv_sm.adv_txdone_ev);
+ ble_ll_adv_tx_done(&g_ble_ll_adv_sm);
}
/**
@@ -1246,6 +1301,13 @@ ble_ll_adv_reset(void)
ble_ll_adv_init();
}
+/* Called to determine if advertising is enabled */
+uint8_t
+ble_ll_adv_enabled(void)
+{
+ return g_ble_ll_adv_sm.enabled;
+}
+
/**
* Initialize the advertising functionality of a BLE device. This should
* be called once on initialization
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 4566d10..373909b 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -32,6 +32,13 @@
#include "hal/hal_cputime.h"
#include "hal/hal_gpio.h"
+/*
+ * XXX: looks like the current code will allow the 1st packet in a
+ * connection to extend past the end of the allocated connection end
+ * time. That is not good. Need to deal with that. Need to extend connection
+ * end time.
+ */
+
/* XXX TODO
* 1) Add set channel map command and implement channel change procedure.
* 2) Make sure we have implemented all ways a connection can die/end. Not
@@ -56,8 +63,22 @@
* the host that issued the create connection.
* 9) How does peer address get set if we are using whitelist? Look at filter
* policy and make sure you are doing this correctly.
+ * 10) Right now I use a fixed definition for required slots. CHange this.
+ * 11) Use output compare for transmit.
+ */
+
+/*
+ * XXX: How should we deal with a late connection event? We need to determine
+ * what we want to do under the following cases:
+ * 1) The current connection event has not ended but a schedule item starts
+ * 2) The connection event start cb is called but we are later than we
+ * expected. What to do? If we cant transmit at correct point in slot we
+ * are hosed. Well, anchor point can get really messed up!
*/
+/* XXX: we need to make sure we hit the proper tx time for the anchor or we
+ could mess up the slave. Use output compare */
+
/* XXX: this does not belong here! Move to transport? */
extern int ble_hs_rx_data(struct os_mbuf *om);
@@ -76,19 +97,25 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
* XXX: move this definition and figure out how we determine the worst-case
* jitter (spec. should have this).
*/
-#define BLE_LL_WFR_USECS (BLE_LL_IFS + 40 + 32)
+#define BLE_LL_WFR_USECS (BLE_LL_IFS + 40 + 32)
/* Configuration parameters */
-#define BLE_LL_CONN_CFG_TX_WIN_SIZE (1)
-#define BLE_LL_CONN_CFG_TX_WIN_OFF (0)
-#define BLE_LL_CONN_CFG_MASTER_SCA (BLE_MASTER_SCA_251_500_PPM << 5)
-#define BLE_LL_CONN_CFG_MAX_CONNS (8)
-#define BLE_LL_CONN_CFG_OUR_SCA (500) /* in ppm */
+#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_MAX_CONNS (8)
+#define BLE_LL_CFG_CONN_OUR_SCA (60) /* in ppm */
+#define BLE_LL_CFG_CONN_INIT_SLOTS (8)
+
+/* We cannot have more than 254 connections given our current implementation */
+#if (BLE_LL_CFG_CONN_MAX_CONNS >= 255)
+ #error "Maximum # of connections is 254"
+#endif
/* LL configuration definitions */
#define BLE_LL_CFG_SUPP_MAX_RX_BYTES (251)
-#define BLE_LL_CFG_SUPP_MAX_TX_BYTES (251)
-#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES (251)
+#define BLE_LL_CFG_SUPP_MAX_TX_BYTES (27)
+#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES (27)
/* Sleep clock accuracy table (in ppm) */
static const uint16_t g_ble_sca_ppm_tbl[8] =
@@ -115,7 +142,7 @@ struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm;
/* Connection state machine array */
-struct ble_ll_conn_sm g_ble_ll_conn_sm[BLE_LL_CONN_CFG_MAX_CONNS];
+struct ble_ll_conn_sm g_ble_ll_conn_sm[BLE_LL_CFG_CONN_MAX_CONNS];
/* List of active connections */
struct ble_ll_conn_active_list g_ble_ll_conn_active_list;
@@ -149,6 +176,40 @@ struct ble_ll_conn_stats g_ble_ll_conn_stats;
/* Some helpful macros */
#define BLE_IS_RETRY_M(ble_hdr) ((ble_hdr)->txinfo.flags & BLE_MBUF_HDR_F_TXD)
+int
+ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2)
+{
+ int rc;
+
+ /* Set time that we last serviced the schedule */
+ if ((int32_t)(s1->last_scheduled - s2->last_scheduled) < 0) {
+ rc = 1;
+ } else {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+/**
+ * Called to return the currently running connection state machine end time.
+ * Always called when interrupts are disabled.
+ *
+ * @return uint32_t
+ */
+uint32_t
+ble_ll_conn_get_ce_end_time(void)
+{
+ uint32_t ce_end_time;
+
+ if (g_ble_ll_conn_cur_sm) {
+ ce_end_time = g_ble_ll_conn_cur_sm->ce_end_time;
+ } else {
+ ce_end_time = cputime_get32();
+ }
+ return ce_end_time;
+}
+
/**
* Checks if pdu is a L2CAP pdu, meaning it is not a control pdu nor an empty
* pdu. Called only for transmit PDU's.
@@ -192,9 +253,6 @@ ble_ll_conn_current_sm_over(void)
/* Disable the wfr timer */
ble_ll_wfr_disable();
- /* Remove any scheduled items for this connection */
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, g_ble_ll_conn_cur_sm);
-
/* Link-layer is in standby state now */
ble_ll_state_set(BLE_LL_STATE_STANDBY);
@@ -214,9 +272,11 @@ ble_ll_conn_find_active_conn(uint16_t handle)
{
struct ble_ll_conn_sm *connsm;
- SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) {
- if (connsm->conn_handle == handle) {
- break;
+ connsm = NULL;
+ if ((handle != 0) && (handle <= BLE_LL_CFG_CONN_MAX_CONNS)) {
+ connsm = &g_ble_ll_conn_sm[handle - 1];
+ if (connsm->conn_state == BLE_LL_CONN_STATE_IDLE) {
+ connsm = NULL;
}
}
return connsm;
@@ -264,7 +324,7 @@ ble_ll_conn_calc_window_widening(struct ble_ll_conn_sm *connsm)
if (time_since_last_anchor > 0) {
delta_msec = cputime_ticks_to_usecs(time_since_last_anchor) / 1000;
total_sca_ppm = g_ble_sca_ppm_tbl[connsm->master_sca] +
- BLE_LL_CONN_CFG_OUR_SCA;
+ BLE_LL_CFG_CONN_OUR_SCA;
window_widening = (total_sca_ppm * delta_msec) / 1000;
}
@@ -468,6 +528,7 @@ ble_ll_conn_wfr_timer_exp(void)
struct ble_ll_conn_sm *connsm;
connsm = g_ble_ll_conn_cur_sm;
+ ble_ll_conn_current_sm_over();
if (connsm) {
ble_ll_event_send(&connsm->conn_ev_end);
++g_ble_ll_conn_stats.wfr_expirations;
@@ -488,6 +549,8 @@ ble_ll_conn_wait_txend(void *arg)
{
struct ble_ll_conn_sm *connsm;
+ ble_ll_conn_current_sm_over();
+
connsm = (struct ble_ll_conn_sm *)arg;
ble_ll_event_send(&connsm->conn_ev_end);
}
@@ -679,26 +742,6 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int beg_transition)
}
/**
- * Connection end schedule callback. Called when the scheduled connection
- * event ends.
- *
- * Context: Interrupt
- *
- * @param sch
- *
- * @return int
- */
-static int
-ble_ll_conn_ev_end_sched_cb(struct ble_ll_sched_item *sch)
-{
- struct ble_ll_conn_sm *connsm;
-
- connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
- ble_ll_event_send(&connsm->conn_ev_end);
- return BLE_LL_SCHED_STATE_DONE;
-}
-
-/**
* Schedule callback for start of connection event
*
* Context: Interrupt
@@ -715,18 +758,19 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
uint32_t wfr_time;
struct ble_ll_conn_sm *connsm;
- /* set led */
- gpio_clear(LED_BLINK_PIN);
+ /* XXX: note that we can extend end time here if we want. Look at this */
/* Set current connection state machine */
connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
g_ble_ll_conn_cur_sm = connsm;
+ assert(connsm);
/* Set LL state */
ble_ll_state_set(BLE_LL_STATE_CONNECTION);
/* Log connection event start */
- ble_ll_log(BLE_LL_LOG_ID_CONN_EV_START, connsm->data_chan_index, 0, 0);
+ ble_ll_log(BLE_LL_LOG_ID_CONN_EV_START, connsm->data_chan_index, 0,
+ connsm->ce_end_time);
/* Set channel */
rc = ble_phy_setchan(connsm->data_chan_index, connsm->access_addr,
@@ -736,12 +780,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
rc = ble_ll_conn_tx_data_pdu(connsm, BLE_PHY_TRANSITION_NONE);
if (!rc) {
- sch->next_wakeup = sch->end_time;
- sch->sched_cb = ble_ll_conn_ev_end_sched_cb;
rc = BLE_LL_SCHED_STATE_RUNNING;
} else {
/* Inform LL task of connection event end */
- ble_ll_event_send(&connsm->conn_ev_end);
rc = BLE_LL_SCHED_STATE_DONE;
}
} else {
@@ -749,7 +790,6 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
if (rc) {
/* End the connection event as we have no more buffers */
++g_ble_ll_conn_stats.slave_ce_failures;
- ble_ll_event_send(&connsm->conn_ev_end);
rc = BLE_LL_SCHED_STATE_DONE;
} else {
/*
@@ -758,17 +798,32 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
*/
connsm->slave_set_last_anchor = 1;
+ /*
+ * Set the wait for response time. The anchor point is when we
+ * expect the master to start transmitting. Worst-case, we expect
+ * to hear a reply within the anchor point plus:
+ * -> the current tx window size
+ * -> The current window widening amount
+ * -> Amount of time it takes to detect packet start.
+ */
usecs = connsm->slave_cur_tx_win_usecs + BLE_LL_WFR_USECS +
connsm->slave_cur_window_widening;
wfr_time = connsm->anchor_point + cputime_usecs_to_ticks(usecs);
ble_ll_wfr_enable(wfr_time);
/* Set next wakeup time to connection event end time */
- sch->next_wakeup = sch->end_time;
- sch->sched_cb = ble_ll_conn_ev_end_sched_cb;
rc = BLE_LL_SCHED_STATE_RUNNING;
}
}
+
+ if (rc == BLE_LL_SCHED_STATE_DONE) {
+ ble_ll_event_send(&connsm->conn_ev_end);
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+ g_ble_ll_conn_cur_sm = NULL;
+ }
+
+ /* Set time that we last serviced the schedule */
+ connsm->last_scheduled = cputime_get32();
return rc;
}
@@ -821,71 +876,6 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime)
}
/**
- * Set the schedule for connection events
- *
- * Context: Link Layer task
- *
- * @param connsm
- *
- * @return struct ble_ll_sched_item *
- */
-static struct ble_ll_sched_item *
-ble_ll_conn_sched_set(struct ble_ll_conn_sm *connsm)
-{
- int rc;
- uint32_t usecs;
- struct ble_ll_sched_item *sch;
-
- sch = ble_ll_sched_get_item();
- if (sch) {
- /* Set sched type, arg and callback function */
- sch->sched_type = BLE_LL_SCHED_TYPE_CONN;
- sch->cb_arg = connsm;
- sch->sched_cb = ble_ll_conn_event_start_cb;
-
- /* Set the start time of the event */
- if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
- sch->start_time = connsm->anchor_point -
- cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS);
-
- /* We will attempt to schedule the maximum CE length */
- usecs = connsm->max_ce_len * BLE_LL_CONN_CE_USECS;
- } else {
- /* Include window widening and scheduling delay */
- usecs = connsm->slave_cur_window_widening +
- XCVR_RX_SCHED_DELAY_USECS;
-
- sch->start_time = connsm->anchor_point -
- cputime_usecs_to_ticks(usecs);
-
- /* Schedule entire connection interval for slave */
- usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
- }
-
- /*
- * We must end at least an IFS before the next scheduled event to
- * insure the minimum time between frames.
- */
- usecs -= (BLE_LL_IFS + BLE_LL_PROC_DELAY);
- sch->end_time = connsm->anchor_point + cputime_usecs_to_ticks(usecs);
- connsm->ce_end_time = sch->end_time;
-
- /* XXX: for now, we cant get an overlap so assert on error. */
- /* Add the item to the scheduler */
- rc = ble_ll_sched_add(sch);
- assert(rc == 0);
- } else {
- /* Count # of times we could not set schedule */
- ++g_ble_ll_conn_stats.cant_set_sched;
-
- /* XXX: for now just assert; must handle this later though */
- assert(0);
- }
-
- return sch;
-}
-
-/**
* Connection supervision timer callback; means that the connection supervision
* timeout has been reached and we should perform the appropriate actions.
*
@@ -915,11 +905,13 @@ void
ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm,
struct hci_create_conn *hcc)
{
- /* Must be master */
+ /* Set master role */
connsm->conn_role = BLE_LL_CONN_ROLE_MASTER;
- connsm->tx_win_size = BLE_LL_CONN_CFG_TX_WIN_SIZE;
- connsm->tx_win_off = BLE_LL_CONN_CFG_TX_WIN_OFF;
- connsm->master_sca = BLE_LL_CONN_CFG_MASTER_SCA;
+
+ /* Set default ce parameters */
+ connsm->tx_win_size = BLE_LL_CFG_CONN_TX_WIN_SIZE;
+ connsm->tx_win_off = BLE_LL_CFG_CONN_TX_WIN_OFF;
+ connsm->master_sca = BLE_LL_CFG_CONN_MASTER_SCA;
/* Hop increment is a random value between 5 and 16. */
connsm->hop_inc = (rand() % 12) + 5;
@@ -962,17 +954,22 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm,
/* Calculate random access address and crc initialization value */
connsm->access_addr = ble_ll_conn_calc_access_addr();
connsm->crcinit = rand() & 0xffffff;
+
+ /* Set initial schedule callback */
+ connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
}
/**
- * Start the connection state machine. This is done once per connection
- * when the HCI command "create connection" is issued to the controller or
- * when a slave receives a connect request,
+ * Create a new connection state machine. This is done once per
+ * connection when the HCI command "create connection" is issued to the
+ * controller or when a slave receives a connect request.
+ *
+ * Context: Link Layer task
*
* @param connsm
*/
void
-ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm)
+ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
{
struct ble_ll_conn_global_params *conn_params;
@@ -1030,20 +1027,6 @@ ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm)
connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
- /*
- * Section 4.5.10 Vol 6 PART B. If the max tx/rx time or octets
- * exceeds the minimum, data length procedure needs to occur
- */
- if ((connsm->max_tx_octets > BLE_LL_CONN_SUPP_BYTES_MIN) ||
- (connsm->max_rx_octets > BLE_LL_CONN_SUPP_BYTES_MIN) ||
- (connsm->max_tx_time > BLE_LL_CONN_SUPP_TIME_MIN) ||
- (connsm->max_rx_time > BLE_LL_CONN_SUPP_TIME_MIN)) {
- /* Start the data length update procedure */
- if (ble_ll_read_supp_features() & BLE_LL_FEAT_DATA_LEN_EXT) {
- ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
- }
- }
-
/* Add to list of active connections */
SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle);
}
@@ -1114,13 +1097,8 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
struct os_mbuf *m;
struct os_mbuf_pkthdr *pkthdr;
- /* If this is the current state machine, we need to end it */
- if (connsm == g_ble_ll_conn_cur_sm) {
- ble_ll_conn_current_sm_over();
- } else {
- /* Remove scheduler events just in case */
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, connsm);
- }
+ /* Remove scheduler events just in case */
+ ble_ll_sched_rmv_elem(&connsm->conn_sch);
/* Stop supervision timer */
cputime_timer_stop(&connsm->conn_spvn_timer);
@@ -1173,6 +1151,75 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
ble_ll_log(BLE_LL_LOG_ID_CONN_END,connsm->conn_handle,0,connsm->event_cntr);
}
+static int
+ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
+{
+ uint16_t latency;
+ uint32_t itvl;
+ uint32_t cur_ww;
+ uint32_t max_ww;
+
+ /*
+ * XXX: not quite sure I am interpreting slave latency correctly here.
+ * The spec says if you applied slave latency and you dont hear a packet,
+ * you dont apply slave latency. Does that mean you dont apply slave
+ * latency until you hear a packet or on the next interval if you listen
+ * and dont hear anything, can you apply slave latency?
+ */
+ /* Set event counter to the next connection event that we will tx/rx in */
+ itvl = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
+ latency = 1;
+ if (connsm->allow_slave_latency) {
+ if (connsm->pkt_rxd) {
+ latency += connsm->slave_latency;
+ itvl = itvl * latency;
+ }
+ }
+ connsm->event_cntr += latency;
+
+ /* Set next connection event start time */
+ connsm->anchor_point += cputime_usecs_to_ticks(itvl);
+
+ /* Calculate data channel index of next connection event */
+ connsm->last_unmapped_chan = connsm->unmapped_chan;
+ while (latency > 0) {
+ --latency;
+ connsm->data_chan_index = ble_ll_conn_calc_dci(connsm);
+ }
+
+ /*
+ * If we are trying to terminate connection, check if next wake time is
+ * passed the termination timeout. If so, no need to continue with
+ * connection as we will time out anyway.
+ */
+ if (connsm->pending_ctrl_procs & (1 << BLE_LL_CTRL_PROC_TERMINATE)) {
+ if ((int32_t)(connsm->terminate_timeout - connsm->anchor_point) <= 0) {
+ return -1;
+ }
+ }
+
+ /*
+ * Calculate ce end time. For a slave, we need to add window widening and
+ * the transmit window if we still have one.
+ */
+ itvl = BLE_LL_CFG_CONN_INIT_SLOTS * BLE_LL_SCHED_USECS_PER_SLOT;
+ if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
+ cur_ww = ble_ll_conn_calc_window_widening(connsm);
+ max_ww = (connsm->conn_itvl * (BLE_LL_CONN_ITVL_USECS/2)) - BLE_LL_IFS;
+ if (cur_ww >= max_ww) {
+ return -1;
+ }
+ connsm->slave_cur_window_widening = cur_ww;
+ itvl += cur_ww + connsm->slave_cur_tx_win_usecs;
+ } else {
+ /* We adjust end time for connection to end of time slot */
+ itvl -= XCVR_TX_SCHED_DELAY_USECS;
+ }
+ connsm->ce_end_time = connsm->anchor_point + cputime_usecs_to_ticks(itvl);
+
+ return 0;
+}
+
/**
* Called when a connection has been created. This function will
* -> Set the connection state to created.
@@ -1185,10 +1232,13 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
* Context: Link Layer
*
* @param connsm
+ *
+ * @ return 0: connection NOT created. 1: connection created
*/
-static void
+static int
ble_ll_conn_created(struct ble_ll_conn_sm *connsm, uint32_t endtime)
{
+ int rc;
uint32_t usecs;
/* Set state to created */
@@ -1201,34 +1251,56 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, uint32_t endtime)
/* Clear packet received flag */
connsm->pkt_rxd = 0;
+ /* Consider time created the last scheduled time */
+ connsm->last_scheduled = cputime_get32();
+
/*
- * Set first connection event time. If we are a master, the endtime
- * represents the end of the advertisement that we are transmitting the
- * connect request to. If a slave, it is the end time of connect request.
- * Thus, for the master, we need to add an IFS time plus the time it takes
- * to transmit the connection request. For both master and slave, the
- * actual connection starts 1.25 msecs plus the transmit window offset
- * from the end of the connection request.
+ * Set first connection event time. If slave the endtime is the receive end
+ * time of the connect request. The actual connection starts 1.25 msecs plus
+ * the transmit window offset from the end of the connection request.
*/
+ rc = 1;
connsm->last_anchor_point = endtime;
- if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
- usecs = BLE_LL_CONN_REQ_DURATION + BLE_LL_IFS;
- connsm->last_anchor_point += cputime_usecs_to_ticks(usecs);
-
- } else {
+ if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
connsm->slave_cur_tx_win_usecs =
connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS;
- usecs = 0;
+ usecs = 1250 + (connsm->tx_win_off * BLE_LL_CONN_TX_WIN_USECS);
+ connsm->anchor_point = endtime + cputime_usecs_to_ticks(usecs);
+ usecs = connsm->slave_cur_tx_win_usecs + (BLE_LL_CFG_CONN_INIT_SLOTS *
+ BLE_LL_SCHED_USECS_PER_SLOT);
+ connsm->ce_end_time = connsm->anchor_point +
+ cputime_usecs_to_ticks(usecs);
+ connsm->slave_cur_window_widening = 0;
+
+ /* Start the scheduler for the first connection event */
+ while (ble_ll_sched_slave_new(connsm)) {
+ if (ble_ll_conn_next_event(connsm)) {
+ ++g_ble_ll_conn_stats.cant_set_sched;
+ rc = 0;
+ break;
+ }
+ }
}
- usecs += 1250 + (connsm->tx_win_off * BLE_LL_CONN_TX_WIN_USECS);
- connsm->anchor_point = endtime + cputime_usecs_to_ticks(usecs);
- connsm->slave_cur_window_widening = 0;
/* Send connection complete event to inform host of connection */
- ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS);
+ if (rc) {
+ /*
+ * Section 4.5.10 Vol 6 PART B. If the max tx/rx time or octets
+ * exceeds the minimum, data length procedure needs to occur
+ */
+ if ((connsm->max_tx_octets > BLE_LL_CONN_SUPP_BYTES_MIN) ||
+ (connsm->max_rx_octets > BLE_LL_CONN_SUPP_BYTES_MIN) ||
+ (connsm->max_tx_time > BLE_LL_CONN_SUPP_TIME_MIN) ||
+ (connsm->max_rx_time > BLE_LL_CONN_SUPP_TIME_MIN)) {
+ /* Start the data length update procedure */
+ if (ble_ll_read_supp_features() & BLE_LL_FEAT_DATA_LEN_EXT) {
+ ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
+ }
+ }
+ ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS);
+ }
- /* Start the scheduler for the first connection event */
- ble_ll_conn_sched_set(connsm);
+ return rc;
}
/**
@@ -1243,17 +1315,18 @@ void
ble_ll_conn_event_end(void *arg)
{
uint8_t ble_err;
- uint16_t latency;
- uint32_t itvl;
- uint32_t cur_ww;
- uint32_t max_ww;
struct ble_ll_conn_sm *connsm;
+ /* Better be a connection state machine! */
connsm = (struct ble_ll_conn_sm *)arg;
- assert(connsm && (connsm == g_ble_ll_conn_cur_sm));
+ assert(connsm);
- /* The current state machine is over */
- ble_ll_conn_current_sm_over();
+ /* Check if we need to resume scanning */
+ ble_ll_scan_chk_resume();
+
+ /* Log event end */
+ ble_ll_log(BLE_LL_LOG_ID_CONN_EV_END, 0, connsm->event_cntr,
+ connsm->ce_end_time);
/* If we have transmitted the terminate IND successfully, we are done */
if ((connsm->terminate_ind_txd) || (connsm->terminate_ind_rxd)) {
@@ -1281,79 +1354,30 @@ ble_ll_conn_event_end(void *arg)
connsm->slave_cur_tx_win_usecs = 0;
}
- /*
- * XXX: not quite sure I am interpreting slave latency correctly here.
- * The spec says if you applied slave latency and you dont hear a packet,
- * you dont apply slave latency. Does that mean you dont apply slave
- * latency until you hear a packet or on the next interval if you listen
- * and dont hear anything, can you apply slave latency?
- */
- /* Set event counter to the next connection event that we will tx/rx in */
- itvl = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
- latency = 1;
- if (connsm->allow_slave_latency) {
- if (connsm->pkt_rxd) {
- latency += connsm->slave_latency;
- itvl = itvl * latency;
- }
- }
- connsm->event_cntr += latency;
-
- /* Set next connection event start time */
- connsm->anchor_point += cputime_usecs_to_ticks(itvl);
-
- /* Calculate data channel index of next connection event */
- connsm->last_unmapped_chan = connsm->unmapped_chan;
- while (latency > 0) {
- --latency;
- connsm->data_chan_index = ble_ll_conn_calc_dci(connsm);
- }
-
- /* We better not be late for the anchor point. If so, skip events */
- while ((int32_t)(connsm->anchor_point - cputime_get32()) <= 0) {
- ++connsm->event_cntr;
- connsm->data_chan_index = ble_ll_conn_calc_dci(connsm);
- connsm->anchor_point +=
- cputime_usecs_to_ticks(connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS);
- ++g_ble_ll_conn_stats.conn_ev_late;
+ /* Move to next connection event */
+ if (ble_ll_conn_next_event(connsm)) {
+ ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL);
+ return;
}
/* Reset "per connection event" variables */
connsm->cons_rxd_bad_crc = 0;
connsm->pkt_rxd = 0;
- /*
- * If we are trying to terminate connection, check if next wake time is
- * passed the termination timeout. If so, no need to continue with
- * connection as we will time out anyway.
- */
- if (connsm->pending_ctrl_procs & (1 << BLE_LL_CTRL_PROC_TERMINATE)) {
- if ((int32_t)(connsm->terminate_timeout - connsm->anchor_point) <= 0) {
- ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL);
- return;
- }
- }
+ /* See if we need to start any control procedures */
+ ble_ll_ctrl_chk_proc_start(connsm);
- /* Calculate window widening for next event. If too big, end conn */
- if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) {
- cur_ww = ble_ll_conn_calc_window_widening(connsm);
- max_ww = (connsm->conn_itvl * (BLE_LL_CONN_ITVL_USECS/2)) - BLE_LL_IFS;
- if (cur_ww >= max_ww) {
+ /* Set initial schedule callback */
+ connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
+
+ /* Schedule the next connection event */
+ while (ble_ll_sched_conn_reschedule(connsm)) {
+ if (ble_ll_conn_next_event(connsm)) {
ble_ll_conn_end(connsm, BLE_ERR_CONN_TERM_LOCAL);
return;
}
- connsm->slave_cur_window_widening = cur_ww;
}
- /* Log event end */
- ble_ll_log(BLE_LL_LOG_ID_CONN_EV_END, 0, 0, connsm->event_cntr);
-
- /* See if we need to start any control procedures */
- ble_ll_ctrl_chk_proc_start(connsm);
-
- /* Schedule the next connection event */
- ble_ll_conn_sched_set(connsm);
-
/* If we have completed packets, send an event */
if (connsm->completed_pkts) {
ble_ll_conn_num_comp_pkts_event_send();
@@ -1367,9 +1391,11 @@ ble_ll_conn_event_end(void *arg)
* @param m
* @param adva
* @param addr_type
+ * @param txoffset The tx window offset for this connection
*/
-void
-ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type)
+static void
+ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type,
+ uint16_t txoffset)
{
uint8_t pdu_type;
uint8_t *dptr;
@@ -1391,7 +1417,8 @@ ble_ll_conn_req_pdu_update(struct os_mbuf *m, uint8_t *adva, uint8_t addr_type)
ble_hdr->txinfo.hdr_byte = pdu_type;
dptr = m->om_data;
- memcpy(dptr + BLE_DEV_ADDR_LEN, adva, BLE_DEV_ADDR_LEN);
+ memcpy(dptr + BLE_DEV_ADDR_LEN, adva, BLE_DEV_ADDR_LEN);
+ htole16(dptr + 20, txoffset);
}
/* Returns true if the address matches the connection peer address */
@@ -1414,6 +1441,19 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
}
/**
+ * Called when a connect request transmission is done.
+ *
+ * Context: ISR
+ *
+ * @param arg
+ */
+static void
+ble_ll_conn_req_txend(void *arg)
+{
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+}
+
+/**
* Send a connection requestion to an advertiser
*
* Context: Interrupt
@@ -1422,18 +1462,38 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
* @param adva Address of advertiser
*/
static int
-ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva)
+ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva, uint16_t txoffset)
{
int rc;
struct os_mbuf *m;
m = ble_ll_scan_get_pdu();
- ble_ll_conn_req_pdu_update(m, adva, addr_type);
+ ble_ll_conn_req_pdu_update(m, adva, addr_type, txoffset);
+ ble_phy_set_txend_cb(ble_ll_conn_req_txend, NULL);
rc = ble_phy_tx(m, BLE_PHY_TRANSITION_RX_TX, BLE_PHY_TRANSITION_NONE);
return rc;
}
/**
+ * Called when a schedule item overlaps the currently running connection
+ * event. This generally should not happen, but if it does we stop the
+ * current connection event to let the schedule item run.
+ *
+ * NOTE: the phy has been disabled as well as the wfr timer before this is
+ * called.
+ */
+void
+ble_ll_conn_event_halt(void)
+{
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+ if (g_ble_ll_conn_cur_sm) {
+ g_ble_ll_conn_cur_sm->pkt_rxd = 0;
+ ble_ll_event_send(&g_ble_ll_conn_cur_sm->conn_ev_end);
+ g_ble_ll_conn_cur_sm = NULL;
+ }
+}
+
+/**
* Process a received PDU while in the initiating state.
*
* Context: Link Layer task.
@@ -1449,12 +1509,9 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
/* Get the connection state machine we are trying to create */
connsm = g_ble_ll_conn_create_sm;
- if (!connsm) {
- return;
- }
/* If we have sent a connect request, we need to enter CONNECTION state*/
- if (ble_hdr->rxinfo.crcok &&
+ if (connsm && BLE_MBUF_HDR_CRC_OK(ble_hdr) &&
(ble_hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_REQ_TXD)) {
/* Set address of advertiser to which we are connecting. */
if (!ble_ll_scan_whitelist_enabled()) {
@@ -1477,15 +1534,15 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
/* Connection has been created. Stop scanning */
g_ble_ll_conn_create_sm = NULL;
- ble_ll_scan_sm_stop(ble_ll_scan_sm_get(), 1);
+ ble_ll_scan_sm_stop(0);
ble_ll_conn_created(connsm, ble_hdr->end_cputime);
} else {
- ble_ll_scan_resume();
+ ble_ll_scan_chk_resume();
}
}
/**
- * Called when a receive PDU has ended.
+ * Called when a receive PDU has ended and we are in the initiating state.
*
* Context: Interrupt
*
@@ -1497,7 +1554,7 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
* > 0: Do not disable PHY as that has already been done.
*/
int
-ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
+ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
{
int rc;
int chk_send_req;
@@ -1508,6 +1565,20 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
uint8_t *rxbuf;
struct ble_mbuf_hdr *ble_hdr;
+ /*
+ * We have to restart receive if we cant hand up pdu. We return 0 so that
+ * the phy does not get disabled.
+ */
+ if (!rxpdu) {
+ ble_phy_rx();
+ return 0;
+ }
+
+ rc = -1;
+ if (!crcok) {
+ goto init_rx_isr_exit;
+ }
+
/* Only interested in ADV IND or ADV DIRECT IND */
rxbuf = rxpdu->om_data;
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
@@ -1531,7 +1602,6 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
}
/* Should we send a connect request? */
- rc = -1;
if (chk_send_req) {
/* Check filter policy */
adv_addr = rxbuf + BLE_LL_PDU_HDR_LEN;
@@ -1560,18 +1630,63 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
}
}
- /* Setup to transmit the connect request */
- rc = ble_ll_conn_request_send(addr_type, adv_addr);
- if (!rc) {
- ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_REQ_TXD;
- ++g_ble_ll_conn_stats.conn_req_txd;
+ /* 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,
+ BLE_LL_CFG_CONN_INIT_SLOTS)) {
+ /* Setup to transmit the connect request */
+ rc = ble_ll_conn_request_send(addr_type, adv_addr,
+ g_ble_ll_conn_create_sm->tx_win_off);
+ if (!rc) {
+ ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_REQ_TXD;
+ ++g_ble_ll_conn_stats.conn_req_txd;
+ }
+ } else {
+ /* Count # of times we could not set schedule */
+ ++g_ble_ll_conn_stats.cant_set_sched;
}
}
+init_rx_isr_exit:
+ if (rc) {
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+ }
return rc;
}
/**
+ * Function called when a timeout has occurred for a connection. There are
+ * two types of timeouts: a connection supervision timeout and control
+ * procedure timeout.
+ *
+ * Context: Link Layer task
+ *
+ * @param connsm
+ * @param ble_err
+ */
+void
+ble_ll_conn_timeout(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
+{
+ int was_current;
+ os_sr_t sr;
+
+ was_current = 0;
+ OS_ENTER_CRITICAL(sr);
+ if (g_ble_ll_conn_cur_sm == connsm) {
+ ble_ll_conn_current_sm_over();
+ was_current = 1;
+ }
+ OS_EXIT_CRITICAL(sr);
+
+ /* Check if we need to resume scanning */
+ if (was_current) {
+ ble_ll_scan_chk_resume();
+ }
+
+ ble_ll_conn_end(connsm, ble_err);
+}
+
+/**
* Connection supervision timeout. When called, it means that the connection
* supervision timeout has been reached. If reached, we end the connection.
*
@@ -1582,16 +1697,18 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
void
ble_ll_conn_spvn_timeout(void *arg)
{
- ble_ll_conn_end((struct ble_ll_conn_sm *)arg, BLE_ERR_CONN_SPVN_TMO);
+ ble_ll_conn_timeout((struct ble_ll_conn_sm *)arg, BLE_ERR_CONN_SPVN_TMO);
}
/**
* Called when a data channel PDU has started that matches the access
* address of the current connection. Note that the CRC of the PDU has not
- * been checked yet.
+ * been checked yet.
+ *
+ * Context: Interrupt
*/
void
-ble_ll_conn_rx_pdu_start(void)
+ble_ll_conn_rx_isr_start(void)
{
struct ble_ll_conn_sm *connsm;
@@ -1613,10 +1730,11 @@ ble_ll_conn_rx_pdu_start(void)
*
* Context: Link layer task
*
- * @param rxpdu
+ * @param rxpdu Pointer to received pdu
+ * @param rxpdu Pointer to ble mbuf header of received pdu
*/
void
-ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
+ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
{
uint8_t hdr_byte;
uint8_t rxd_sn;
@@ -1625,13 +1743,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
uint16_t acl_hdr;
uint32_t tmo;
struct ble_ll_conn_sm *connsm;
-
- if (crcok) {
+
+ if (BLE_MBUF_HDR_CRC_OK(hdr)) {
/* Count valid received data pdus */
++g_ble_ll_stats.rx_valid_data_pdus;
+ /* XXX: there is a chance that the connection was thrown away and
+ re-used before processing packets here. Fix this. */
/* We better have a connection state machine */
- connsm = g_ble_ll_conn_cur_sm;
+ connsm = ble_ll_conn_find_active_conn(hdr->rxinfo.handle);
if (connsm) {
/* Reset the connection supervision timeout */
cputime_timer_stop(&connsm->conn_spvn_timer);
@@ -1724,7 +1844,7 @@ conn_rx_data_pdu_end:
* > 0: Do not disable PHY as that has already been done.
*/
int
-ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa)
+ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa)
{
int rc;
uint8_t hdr_byte;
@@ -1744,26 +1864,29 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa)
* We should have a current connection state machine. If we dont, we just
* hand the packet to the higher layer to count it.
*/
+ rc = -1;
connsm = g_ble_ll_conn_cur_sm;
if (!connsm) {
++g_ble_ll_conn_stats.rx_data_pdu_no_conn;
- return -1;
+ goto conn_exit;
}
/* Double check access address. Better match connection state machine! */
if (aa != connsm->access_addr) {
++g_ble_ll_conn_stats.rx_data_pdu_bad_aa;
- ble_ll_event_send(&connsm->conn_ev_end);
- return -1;
+ goto conn_exit;
}
+ /* Set the handle in the ble mbuf header */
+ rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
+ rxhdr->rxinfo.handle = connsm->conn_handle;
+
/*
* Check the packet CRC. A connection event can continue even if the
* received PDU does not pass the CRC check. If we receive two consecutive
* CRC errors we end the conection event.
*/
- rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
- if (!rxhdr->rxinfo.crcok) {
+ if (!BLE_MBUF_HDR_CRC_OK(rxhdr)) {
/*
* Increment # of consecutively received CRC errors. If more than
* one we will end the connection event.
@@ -1894,19 +2017,24 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa)
}
conn_rx_pdu_end:
- /* Set last anchor point if 1st received frame in connection event */
+ /* Set anchor point (and last) if 1st received frame in connection event */
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]);
+ connsm->anchor_point = connsm->last_anchor_point;
}
/* Send link layer a connection end event if over */
+conn_exit:
if (rc) {
- ble_ll_event_send(&connsm->conn_ev_end);
+ ble_ll_conn_current_sm_over();
+ if (connsm) {
+ ble_ll_event_send(&connsm->conn_ev_end);
+ }
}
- return 0;
+ return rc;
}
/**
@@ -1999,12 +2127,14 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length)
* Context: Link Layer
*
* @param rxbuf Pointer to received PDU
+ * @param conn_req_end receive end time of connect request
*
* @return 0: connection not started; 1 connecton started
*/
int
ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end)
{
+ int rc;
uint32_t temp;
uint32_t crcinit;
uint8_t *inita;
@@ -2096,11 +2226,17 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint32_t conn_req_end)
/* Start the connection state machine */
connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE;
- ble_ll_conn_sm_start(connsm);
+ ble_ll_conn_sm_new(connsm);
- /* The connection has been created. */
- ble_ll_conn_created(connsm, conn_req_end);
- return 1;
+ /* Set initial schedule callback */
+ connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
+
+ rc = ble_ll_conn_created(connsm, conn_req_end);
+ if (!rc) {
+ SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
+ STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
+ }
+ return rc;
err_slave_start:
STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
@@ -2109,7 +2245,9 @@ err_slave_start:
}
/**
- * Called to reset the connection module.
+ * Called to reset the connection module. When this function is called the
+ * scheduler has been stopped and the phy has been disabled. The LL should
+ * be in the standby state.
*
* Context: Link Layer task
*/
@@ -2121,7 +2259,7 @@ ble_ll_conn_reset(void)
/* Kill the current one first (if one is running) */
if (g_ble_ll_conn_cur_sm) {
connsm = g_ble_ll_conn_cur_sm;
- ble_ll_conn_current_sm_over();
+ g_ble_ll_conn_cur_sm = NULL;
ble_ll_conn_end(connsm, BLE_ERR_SUCCESS);
}
@@ -2155,7 +2293,7 @@ ble_ll_conn_module_init(void)
* the specification allows a handle of zero; we just avoid using it.
*/
connsm = &g_ble_ll_conn_sm[0];
- for (i = 0; i < BLE_LL_CONN_CFG_MAX_CONNS; ++i) {
+ for (i = 0; i < BLE_LL_CFG_CONN_MAX_CONNS; ++i) {
connsm->conn_handle = i + 1;
STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
@@ -2170,6 +2308,9 @@ ble_ll_conn_module_init(void)
ble_ll_mbuf_init(m, 0, BLE_LL_LLID_DATA_FRAG);
+ /* Initialize fixed schedule elements */
+ connsm->conn_sch.sched_type = BLE_LL_SCHED_TYPE_CONN;
+ connsm->conn_sch.cb_arg = connsm;
++connsm;
}
@@ -2187,3 +2328,4 @@ ble_ll_conn_module_init(void)
conn_params->conn_init_max_tx_time = BLE_TX_DUR_USECS_M(maxbytes);
conn_params->conn_init_max_tx_octets = BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES;
}
+
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 a4ac46c..a051318 100644
--- a/net/nimble/controller/src/ble_ll_conn_hci.c
+++ b/net/nimble/controller/src/ble_ll_conn_hci.c
@@ -358,7 +358,7 @@ ble_ll_conn_create(uint8_t *cmdbuf)
/* Initialize state machine in master role and start state machine */
ble_ll_conn_master_init(connsm, hcc);
- ble_ll_conn_sm_start(connsm);
+ ble_ll_conn_sm_new(connsm);
/* Create the connection request */
ble_ll_conn_req_pdu_make(connsm);
@@ -400,7 +400,7 @@ ble_ll_conn_create_cancel(void)
if (connsm && (connsm->conn_state == BLE_LL_CONN_STATE_IDLE)) {
/* stop scanning and end the connection event */
g_ble_ll_conn_create_sm = NULL;
- ble_ll_scan_sm_stop(ble_ll_scan_sm_get(), 0);
+ ble_ll_scan_sm_stop(1);
ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID);
rc = BLE_ERR_SUCCESS;
} else {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 48304b2..47015a3 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -32,6 +32,7 @@
#define BLE_LL_CONN_SUPP_BYTES_MAX (251) /* bytes */
/* Connection event timing */
+#define BLE_LL_CONN_INITIAL_OFFSET (1250)
#define BLE_LL_CONN_ITVL_USECS (1250)
#define BLE_LL_CONN_TX_WIN_USECS (1250)
#define BLE_LL_CONN_CE_USECS (625)
@@ -60,7 +61,7 @@ extern struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
struct ble_ll_len_req;
struct hci_create_conn;
struct ble_mbuf_hdr;
-void ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm);
+void ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm);
void ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err);
void ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om,
uint8_t hdr_byte, uint8_t length);
@@ -80,12 +81,15 @@ void ble_ll_conn_reset(void);
void ble_ll_conn_event_end(void *arg);
void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len);
void ble_ll_conn_spvn_timeout(void *arg);
-void ble_ll_conn_rx_pdu_start(void);
-int ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa);
-void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok);
+void ble_ll_conn_rx_isr_start(void);
+int ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu, uint32_t aa);
+void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr);
void ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr);
-int ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu);
+int ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
void ble_ll_conn_wfr_timer_exp(void);
+int ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2);
+uint32_t ble_ll_conn_get_ce_end_time(void);
+void ble_ll_conn_event_halt(void);
/* HCI */
void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm,
@@ -96,5 +100,7 @@ int ble_ll_conn_create(uint8_t *cmdbuf);
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);
+void ble_ll_conn_timeout(struct ble_ll_conn_sm *connsm, uint8_t ble_err);
+
#endif /* H_BLE_LL_CONN_PRIV_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/b6e2b5ff/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 2a06265..0e5df2d 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -197,7 +197,7 @@ void
ble_ll_ctrl_proc_rsp_timer_cb(void *arg)
{
/* Control procedure has timed out. Kill the connection */
- ble_ll_conn_end((struct ble_ll_conn_sm *)arg, BLE_ERR_LMP_LL_RSP_TMO);
+ ble_ll_conn_timeout((struct ble_ll_conn_sm *)arg, BLE_ERR_LMP_LL_RSP_TMO);
}
/**