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 2015/11/19 20:33:24 UTC
[1/3] incubator-mynewt-larva git commit: Additional connection code:
supervision timeout, connection scheduling, start/end event processing
Repository: incubator-mynewt-larva
Updated Branches:
refs/heads/master 9504907f2 -> c9d16694d
Additional connection code: supervision timeout, connection scheduling, start/end event processing
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/47dff3ec
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/47dff3ec
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/47dff3ec
Branch: refs/heads/master
Commit: 47dff3ec49a857efa192706c8175eacdb0073c5c
Parents: c7cc3d0
Author: wes3 <wi...@micosa.io>
Authored: Thu Nov 19 11:30:58 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Thu Nov 19 11:31:04 2015 -0800
----------------------------------------------------------------------
libs/os/include/os/os_mbuf.h | 6 +-
.../controller/include/controller/ble_ll.h | 74 +-
.../controller/include/controller/ble_ll_conn.h | 7 +-
.../include/controller/ble_ll_sched.h | 3 +-
.../controller/include/controller/ble_phy.h | 2 +-
net/nimble/controller/src/ble_ll.c | 127 +--
net/nimble/controller/src/ble_ll_adv.c | 5 +-
net/nimble/controller/src/ble_ll_conn.c | 926 ++++++++++++++++---
net/nimble/controller/src/ble_ll_scan.c | 17 +-
net/nimble/controller/src/ble_ll_sched.c | 15 +-
net/nimble/controller/src/ble_ll_whitelist.c | 1 -
net/nimble/drivers/native/src/ble_phy.c | 4 +-
net/nimble/drivers/nrf52/src/ble_phy.c | 34 +-
net/nimble/host/src/host_hci_cmd.c | 2 +-
net/nimble/include/nimble/ble.h | 6 +-
project/bletest/src/main.c | 82 +-
16 files changed, 996 insertions(+), 315 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/libs/os/include/os/os_mbuf.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h
index 8edbe89..a4d4075 100644
--- a/libs/os/include/os/os_mbuf.h
+++ b/libs/os/include/os/os_mbuf.h
@@ -111,10 +111,14 @@ struct os_mbuf {
#define OS_MBUF_IS_PKTHDR(__om) \
((__om)->om_flags & OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR))
-
+/* Get a packet header pointer given an mbuf pointer */
#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
+/* Given a mbuf packet header pointer, return a pointer to the mbuf */
+#define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
+ (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
+
/*
* Access the data of a mbuf, and cast it to type
*
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 317cb2c..91ff4cf 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -17,33 +17,28 @@
#ifndef H_BLE_LL_
#define H_BLE_LL_
-/* XXX: Not sure this should go here, but whatever */
/*
- * ble ll global parameters
- *
- * NOTES:
- * 1) Controller should not change value of supported max tx and rx time and
- * octets.
+ * Global Link Layer data object. There is only one Link Layer data object
+ * per controller although there may be many instances of the link layer state
+ * machine running.
*/
-struct ble_ll_global_params
-{
- int conn_init_max_tx_octets;
- int conn_init_max_tx_time;
- int supp_max_tx_octets;
- int supp_max_tx_time;
- int supp_max_rx_octets;
- int supp_max_rx_time;
-};
-
struct ble_ll_obj
{
+ /* Current Link Layer state */
uint8_t ll_state;
+
+ /* Task event queue */
struct os_eventq ll_evq;
- struct ble_ll_global_params ll_params;
+
+ /* Receive packet (from phy) event */
struct os_event ll_rx_pkt_ev;
+
+ /* Packet receive queue */
STAILQ_HEAD(ll_rxpkt_qh, os_mbuf_pkthdr) ll_rx_pkt_q;
};
+extern struct ble_ll_obj g_ble_ll_data;
+/* Link layer statistics */
struct ble_ll_stats
{
uint32_t rx_crc_ok;
@@ -61,10 +56,9 @@ struct ble_ll_stats
uint32_t hci_cmds;
uint32_t hci_cmd_errs;
uint32_t hci_events_sent;
+ uint32_t bad_ll_state;
};
-
extern struct ble_ll_stats g_ble_ll_stats;
-extern struct ble_ll_obj g_ble_ll_data;
/* States */
#define BLE_LL_STATE_STANDBY (0)
@@ -78,6 +72,8 @@ extern struct ble_ll_obj g_ble_ll_data;
#define BLE_LL_EVENT_ADV_TXDONE (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_CONN_SPVN_TMO (OS_EVENT_T_PERUSER + 4)
+#define BLE_LL_EVENT_CONN_EV_END (OS_EVENT_T_PERUSER + 5)
/* LL Features */
#define BLE_LL_FEAT_LE_ENCRYPTION (0x01)
@@ -162,7 +158,7 @@ struct ble_dev_addr
/*
* Data Channel format
*
- * -> Header (2 bytes.
+ * -> Header (2 bytes)
* -> LSB contains llid, nesn, sn and md
* -> MSB contains length (8 bits)
* -> Payload (0 to 251)
@@ -173,6 +169,7 @@ struct ble_dev_addr
#define BLE_LL_DATA_HDR_SN_MASK (0x08)
#define BLE_LL_DATA_HDR_MD_MASK (0x10)
#define BLE_LL_DATA_HDR_RSRVD_MASK (0xE0)
+#define BLE_LL_DATA_MAX_OVERHEAD (6)
/* LLID definitions */
#define BLE_LL_LLID_RSRVD (0)
@@ -383,39 +380,8 @@ struct ble_ll_len_req
* hop_inc: Hop increment used for frequency hopping. Random value in
* range of 5 to 16.
*/
-#define BLE_CONNECT_REQ_LEN (34)
-
-struct ble_conn_req_data
-{
- uint32_t aa;
- uint8_t crc_init[3];
- uint8_t winsize;
- uint16_t winoffset;
- uint16_t interval;
- uint16_t latency;
- uint16_t timeout;
- uint8_t chanmap[5];
- uint8_t hop_inc;
- uint8_t master_sca;
-};
-
-#define BLE_CONN_REQ_HOP_MASK (0x1F)
-#define BLE_CONN_REQ_SCA_MASK (0xE0)
-
-/*
- * Initiator filter policy
- *
- * Determines how the initiator's Link Layer processes advertisements.
- *
- * LIST: process connectable advertisements only from devices in white list.
- * SINGLE: do not use white list; process connectable advertisements from
- * a single specific device specified by the host.
- */
-enum ble_ll_init_filt_policy
-{
- BLE_LL_INIT_FILT_LIST = 0,
- BLE_LL_INIT_FILT_SINGLE,
-};
+#define BLE_CONNECT_REQ_LEN (34)
+#define BLE_CONNECT_REQ_PDU_LEN (BLE_CONNECT_REQ_LEN + BLE_LL_PDU_HDR_LEN)
/*--- External API ---*/
/* Initialize the Link Layer */
@@ -435,7 +401,7 @@ int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type);
/*--- PHY interfaces ---*/
/* Called by the PHY when a packet has started */
-int ble_ll_rx_start(struct os_mbuf *rxpdu);
+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 crcok);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 ff62ff6..4c3d535 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -31,9 +31,12 @@ int ble_ll_conn_create(uint8_t *cmdbuf);
int ble_ll_conn_create_cancel(void);
int ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva);
int ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva);
-void ble_ll_init_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, uint8_t crcok);
+void ble_ll_init_rx_pdu_proc(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_pdu_start(uint8_t pdu_type);
void ble_ll_conn_slave_start(uint8_t *rxbuf);
+void ble_ll_conn_spvn_timeout(void *arg);
+void ble_ll_conn_event_end(void *arg);
+void ble_ll_conn_init(void);
+void ble_ll_conn_rsp_rxd(void);
#endif /* H_BLE_LL_CONN_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 eae0cc5..48914ae 100644
--- a/net/nimble/controller/include/controller/ble_ll_sched.h
+++ b/net/nimble/controller/include/controller/ble_ll_sched.h
@@ -25,6 +25,7 @@
#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)
/* Return values for schedule callback. */
#define BLE_LL_SCHED_STATE_RUNNING (0)
@@ -49,7 +50,7 @@ struct ble_ll_sched_item
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);
+int ble_ll_sched_rmv(uint8_t sched_type, void *cb_arg);
/* Initialize the scheduler */
int ble_ll_sched_init(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index 0119b44..2a2103f 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -82,7 +82,7 @@ int ble_phy_init(void);
int ble_phy_reset(void);
/* Set the PHY channel */
-int ble_phy_setchan(uint8_t chan);
+int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit);
/* Place the PHY into transmit mode */
int ble_phy_tx(struct os_mbuf *, uint8_t beg_trans, uint8_t end_trans);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 645fdde..691a057 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -33,7 +33,17 @@
* to see if a packet is "for us". I am referring to packets that pass
* whitelisting but also need to be "for us" (connect requests, scan requests,
* scan responses, etc). Look into this. This way I would not need to do
- additional whitelist checks at the upper layer. */
+ * additional whitelist checks at the upper layer.
+ */
+
+/*
+ * 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:
*
@@ -44,10 +54,6 @@
*
*/
-/* Connection related define */
-#define BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS (27)
-#define BLE_LL_CONN_INIT_MAX_REMOTE_TIME (238)
-
/* The global BLE LL data object */
struct ble_ll_obj g_ble_ll_data;
@@ -60,47 +66,11 @@ struct ble_ll_stats g_ble_ll_stats;
struct os_task g_ble_ll_task;
os_stack_t g_ble_ll_stack[BLE_LL_STACK_SIZE];
-/* XXX: this is just temporary; used to calculate the channel index */
-struct ble_ll_sm_connection
-{
- /* Flow control */
- uint8_t tx_seq;
- uint8_t next_exp_seq;
-
- /* Parameters kept by the link-layer per connection */
- uint8_t max_tx_octets;
- uint8_t max_rx_octets;
- uint8_t max_tx_time;
- uint8_t max_rx_time;
- uint8_t remote_max_tx_octets;
- uint8_t remote_max_rx_octets;
- uint8_t remote_max_tx_time;
- uint8_t remote_max_rx_time;
- uint8_t effective_max_tx_octets;
- uint8_t effective_max_rx_octets;
- uint8_t effective_max_tx_time;
- uint8_t effective_max_rx_time;
-
- /* The connection request data */
- struct ble_conn_req_data req_data;
-};
-
-/* Called when a connection gets initialized */
-int
-ble_init_conn_sm(struct ble_ll_sm_connection *cnxn)
-{
- cnxn->max_tx_time = g_ble_ll_data.ll_params.conn_init_max_tx_time;
- cnxn->max_rx_time = g_ble_ll_data.ll_params.supp_max_rx_time;
- cnxn->max_tx_octets = g_ble_ll_data.ll_params.conn_init_max_tx_octets;
- cnxn->max_rx_octets = g_ble_ll_data.ll_params.supp_max_rx_octets;
- cnxn->remote_max_rx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
- cnxn->remote_max_tx_octets = BLE_LL_CONN_INIT_MAX_REMOTE_OCTETS;
- cnxn->remote_max_rx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
- cnxn->remote_max_tx_time = BLE_LL_CONN_INIT_MAX_REMOTE_TIME;
-
- return 0;
-}
-
+/**
+ * Counts received packets by type
+ *
+ * @param pdu_type
+ */
static void
ble_ll_count_rx_pkts(uint8_t pdu_type)
{
@@ -134,6 +104,8 @@ ble_ll_count_rx_pkts(uint8_t pdu_type)
++g_ble_ll_stats.rx_unk_pdu;
break;
}
+
+ /* XXX: what about data packets? */
}
int
@@ -330,7 +302,7 @@ ble_ll_rx_pkt_in_proc(void)
}
break;
case BLE_LL_STATE_INITIATING:
- ble_ll_init_rx_pdu_proc(pdu_type, rxbuf, ble_hdr->crcok);
+ ble_ll_init_rx_pdu_proc(rxbuf, ble_hdr);
break;
case BLE_LL_STATE_CONNECTION:
/* XXX: implement */
@@ -341,7 +313,7 @@ ble_ll_rx_pkt_in_proc(void)
break;
}
- /* XXX: Free the mbuf for now */
+ /* Free the packet buffer */
os_mbuf_free(&g_mbuf_pool, m);
}
}
@@ -365,14 +337,15 @@ ble_ll_rx_pdu_in(struct os_mbuf *rxpdu)
* Called upon start of received PDU
*
* @param rxpdu
+ * chan
*
* @return int
* < 0: A frame we dont want to receive.
* = 0: Continue to receive frame. Dont go from rx to tx
- * > 1: Continue to receive frame and go from rx to idle when done
+ * > 0: Continue to receive frame and go from rx to tx when done
*/
int
-ble_ll_rx_start(struct os_mbuf *rxpdu)
+ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
{
int rc;
uint8_t pdu_type;
@@ -380,6 +353,26 @@ ble_ll_rx_start(struct os_mbuf *rxpdu)
/* XXX: need to check if this is an adv channel or data channel */
rxbuf = rxpdu->om_data;
+ if (chan < BLE_PHY_NUM_DATA_CHANS) {
+ /*
+ * Data channel pdu. We should be in CONNECTION state with an
+ * ongoing connection
+ */
+ /* XXX: check access address for surety? What to do... */
+ if (g_ble_ll_data.ll_state == BLE_LL_STATE_CONNECTION) {
+ /* Set flag in connection noting we have received a response */
+ ble_ll_conn_rsp_rxd();
+
+ /* Set up to go from rx to tx */
+ rc = 1;
+ } else {
+ ++g_ble_ll_stats.bad_ll_state;
+ rc = 0;
+ }
+ return rc;
+ }
+
+ /* Advertising channel PDU */
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
switch (g_ble_ll_data.ll_state) {
@@ -395,16 +388,24 @@ ble_ll_rx_start(struct os_mbuf *rxpdu)
}
break;
case BLE_LL_STATE_INITIATING:
- rc = ble_ll_init_rx_pdu_start(pdu_type);
+ if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
+ (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND)) {
+ rc = 1;
+ } else {
+ rc = 0;
+ }
break;
case BLE_LL_STATE_SCANNING:
rc = ble_ll_scan_rx_pdu_start(pdu_type, rxpdu);
break;
case BLE_LL_STATE_CONNECTION:
+ /* XXX: This should not happen. What to do? */
+ rc = 0;
+ break;
default:
- /* XXX: should we really assert here? What to do... */
+ /* Should not be in this state */
rc = -1;
- assert(0);
+ ++g_ble_ll_stats.bad_ll_state;
break;
}
@@ -543,6 +544,12 @@ ble_ll_task(void *arg)
case BLE_LL_EVENT_RX_PKT_IN:
ble_ll_rx_pkt_in_proc();
break;
+ case BLE_LL_EVENT_CONN_SPVN_TMO:
+ ble_ll_conn_spvn_timeout(ev->ev_arg);
+ break;
+ case BLE_LL_EVENT_CONN_EV_END:
+ ble_ll_conn_event_end(ev->ev_arg);
+ break;
default:
assert(0);
break;
@@ -589,14 +596,19 @@ ble_ll_event_send(struct os_event *ev)
int
ble_ll_init(void)
{
+ struct ble_ll_obj *lldata;
+
+ /* Get pointer to global data object */
+ lldata = &g_ble_ll_data;
+
/* Initialize the receive queue */
- STAILQ_INIT(&g_ble_ll_data.ll_rx_pkt_q);
+ STAILQ_INIT(&lldata->ll_rx_pkt_q);
/* Initialize eventq */
- os_eventq_init(&g_ble_ll_data.ll_evq);
+ os_eventq_init(&lldata->ll_evq);
/* Initialize receive packet (from phy) event */
- g_ble_ll_data.ll_rx_pkt_ev.ev_type = BLE_LL_EVENT_RX_PKT_IN;
+ lldata->ll_rx_pkt_ev.ev_type = BLE_LL_EVENT_RX_PKT_IN;
/* Initialize LL HCI */
ble_ll_hci_init();
@@ -610,6 +622,9 @@ ble_ll_init(void)
/* Initialize a scanner */
ble_ll_scan_init();
+ /* Initialize the connection module */
+ ble_ll_conn_init();
+
/* Initialize the LL task */
os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, BLE_LL_TASK_PRI,
OS_WAIT_FOREVER, g_ble_ll_stack, BLE_LL_STACK_SIZE);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 67acf8f..08eee0e 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -65,6 +65,7 @@
* 12) Something to consider: if we are attempting to advertise but dont have
* any connection state machines available, I dont think we should enable
* advertising.
+ * 13) Implement high duty cycle advertising timeout.
*/
/*
@@ -381,7 +382,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
gpio_toggle(LED_BLINK_PIN);
/* Set channel */
- rc = ble_phy_setchan(advsm->adv_chan);
+ rc = ble_phy_setchan(advsm->adv_chan, 0, 0);
assert(rc == 0);
/* Set phy mode based on type of advertisement */
@@ -575,7 +576,7 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
ble_ll_whitelist_disable();
/* Remove any scheduled advertising items */
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV);
+ ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_ADV, NULL);
/* Disable advertising */
advsm->enabled = 0;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 58b2097..474af09 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -26,10 +26,13 @@
#include "controller/ble_ll_conn.h"
#include "controller/ble_ll_scan.h"
#include "controller/ble_ll_whitelist.h"
+#include "controller/ble_ll_sched.h"
#include "controller/ble_phy.h"
+#include "hal/hal_cputime.h"
/* XXX TODO
* 1) Implemement connection supervisor timeout.
+ * -> Need to re-start when we receive a packet and set the proper timeout.
* 2) Add set channel map command and implement channel change procedure.
* 3) Closing the connection: the MD bit.
* 4) notifying host about connections: how often do we need to do this? On
@@ -37,79 +40,187 @@
* 5) Deal with window widening. Easy...
* 6) Close connection if window widening gets too big! 4.5.7
* 7) How does state get set to ESTABLISHED? Do that...
- * 8) In both cases when I start the connection SM I need to set up a
- * schedule item to deal with receiving packets and transmitting them.
+ * 8) Set up later connection schedule events.
+ * 8.5) How do we set the end event? Especially if we are receiving? Need
+ * to figure this out.
* 9) Implement flow control and all that.
* 10) Implement getting a data packet. How do we do that?
* 11) Send connection complete event when connection dies.
+ * 12) Data channel index and all that code. Must make sure we are setting this
+ * correctly. Set for 1st connection event but not for other events.
+ * 13) Add more statistics
+ * 14) Update event counter with each event!
+ * 15) Link layer control procedures and timers
+ * 16) Did we implement what happens if we receive a connection request from
+ * a device we are already connected to? We also need to check to see if we
+ * were asked to create a connection when one already exists. Note that
+ * an initiator should only send connection requests to devices it is not
+ * already connected to. Make sure this cant happen.
+ * 17) Dont forget to set pkt_rxd flag for slave latency. Needs to get reset
+ * after each M-S transaction.
+ * 18) Make sure we check incoming data packets for size and all that. You
+ * know, supported octets and all that. For both rx and tx.
+ * 19) Make sure we handle rsp_rxd and pkt_rxd correctly (clearing/checking
+ * setting them).
*/
-/* XXX: Something I need to think about. At what point do I consider the
- * connection created? When I send the connect request or when I send
- * the connection complete event. I just dont want there to be weird race
- * conditions if I get cancel connection create command. I want to make
- * sure that I deal with that properly. I think the connection state will tell
- * me. Anyway, just make sure there are no issues here
- */
+/* Connection event timing */
+#define BLE_LL_CONN_ITVL_USECS (1250)
+#define BLE_LL_CONN_TX_WIN_USECS (1250)
+#define BLE_LL_CONN_CE_USECS (625)
+
+/* XXX: probably should be moved and made more accurate */
+#define BLE_LL_WFR_USECS (100)
/* Channel map size */
-#define BLE_LL_CONN_CHMAP_LEN (5)
+#define BLE_LL_CONN_CHMAP_LEN (5)
/* 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_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)
+
+/* LL configuration definitions */
+#define BLE_LL_CFG_SUPP_MAX_RX_BYTES (27)
+#define BLE_LL_CFG_SUPP_MAX_TX_BYTES (27)
+#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES (27)
/* Roles */
-#define BLE_LL_CONN_ROLE_NONE (0)
-#define BLE_LL_CONN_ROLE_MASTER (1)
-#define BLE_LL_CONN_ROLE_SLAVE (2)
+#define BLE_LL_CONN_ROLE_NONE (0)
+#define BLE_LL_CONN_ROLE_MASTER (1)
+#define BLE_LL_CONN_ROLE_SLAVE (2)
+
+/* Connection states */
+#define BLE_LL_CONN_STATE_IDLE (0)
+#define BLE_LL_CONN_STATE_CREATED (1)
+#define BLE_LL_CONN_STATE_ESTABLISHED (2)
+
+/* Data Lenth Procedure */
+#define BLE_LL_CONN_SUPP_TIME_MIN (328) /* usecs */
+#define BLE_LL_CONN_SUPP_BYTES_MIN (27) /* bytes */
/* Connection request */
-#define BLE_LL_CONN_REQ_ADVA_OFF (BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN)
+#define BLE_LL_CONN_REQ_ADVA_OFF (BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN)
+
+/*
+ * XXX: I just had a thought. Why do I need to allocate connection handles?
+ * For every connection state machine I have I should just give it a handle
+ * inside it. They can sit on the pool and I can use them in round robin
+ * order. This might save some code! This works only if I create the pool
+ * of connections to start.
+ */
+
+/* Global Link Layer connection parameters */
+struct ble_ll_conn_global_params
+{
+ uint8_t supp_max_tx_octets;
+ uint8_t supp_max_rx_octets;
+ uint8_t conn_init_max_tx_octets;
+ uint16_t conn_init_max_tx_time;
+ uint16_t supp_max_tx_time;
+ uint16_t supp_max_rx_time;
+};
-/* Scanning state machine */
+struct ble_ll_conn_global_params g_ble_ll_conn_params;
+
+/* Connection state machine */
struct ble_ll_conn_sm
{
+ /* Current connection state and role */
+ uint8_t conn_state;
+ uint8_t conn_role;
+
+ /* Connection data length management */
+ uint8_t max_tx_octets;
+ uint8_t max_rx_octets;
+ uint8_t rem_max_tx_octets;
+ uint8_t rem_max_rx_octets;
+ uint8_t eff_max_tx_octets;
+ uint8_t eff_max_rx_octets;
+ uint16_t max_tx_time;
+ uint16_t max_rx_time;
+ uint16_t rem_max_tx_time;
+ uint16_t rem_max_rx_time;
+ uint16_t eff_max_tx_time;
+ uint16_t eff_max_rx_time;
+
/* Used to calculate data channel index for connection */
+ uint8_t chanmap[BLE_LL_CONN_CHMAP_LEN];
+ uint8_t hop_inc;
+ uint8_t data_chan_index;
uint8_t unmapped_chan;
uint8_t last_unmapped_chan;
uint8_t num_used_chans;
- uint8_t chanmap[BLE_LL_CONN_CHMAP_LEN];
- uint8_t hop_inc;
- uint8_t conn_state;
- uint8_t conn_role;
+
+ /* connection event timing/mgmt */
+ uint8_t rsp_rxd;
+ uint8_t pkt_rxd;
uint8_t master_sca;
- uint8_t conn_tx_win_size;
- uint8_t own_addr_type;
- uint8_t peer_addr_type;
- uint8_t peer_addr[BLE_DEV_ADDR_LEN];
- uint16_t conn_spvn_tmo;
+ uint8_t tx_win_size;
uint16_t conn_itvl;
- uint16_t conn_slave_latency;
- uint16_t conn_event_cntr;
+ uint16_t slave_latency;
+ uint16_t tx_win_off;
+ uint16_t min_ce_len;
+ uint16_t max_ce_len;
+ uint16_t event_cntr;
+ uint16_t supervision_tmo;
uint16_t conn_handle;
- uint16_t conn_tx_win_off;
uint32_t access_addr;
uint32_t crcinit; /* only low 24 bits used */
+ uint32_t anchor_point;
+
+ /* address information */
+ uint8_t own_addr_type;
+ uint8_t peer_addr_type;
+ uint8_t peer_addr[BLE_DEV_ADDR_LEN];
+
+ /* connection supervisor timer */
+ struct cpu_timer conn_spvn_timer;
+
+ /* connection supervision timeout event */
+ struct os_event conn_spvn_ev;
+
+ /* Connection end event */
+ struct os_event conn_ev_end;
+
+ /* Packet transmit queue */
+ STAILQ_HEAD(conn_txq_head, os_mbuf_pkthdr) conn_txq;
};
-struct ble_ll_conn_sm g_ble_ll_conn_sm;
+/* Pointer to connection state machine we are trying to create */
+struct ble_ll_conn_sm *g_ble_ll_conn_create_sm;
-/* Connection states */
-#define BLE_LL_CONN_STATE_IDLE (0)
-#define BLE_LL_CONN_STATE_CREATED (1)
-#define BLE_LL_CONN_STATE_ESTABLISHED (2)
+/* Pointer to current connection */
+struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm;
/* Connection handles */
static uint8_t g_ble_ll_conn_handles[(BLE_LL_CONN_CFG_MAX_CONNS + 7) / 8];
static uint16_t g_ble_ll_conn_handles_out;
+/* Connection pool elements */
struct os_mempool g_ble_ll_conn_pool;
os_membuf_t g_ble_ll_conn_buf[OS_MEMPOOL_SIZE(BLE_LL_CONN_CFG_MAX_CONNS,
sizeof(struct ble_ll_conn_sm))];
+/* List of active connections */
+static SLIST_HEAD(, ble_hs_conn) g_ble_ll_conn_active_list;
+
+/* Statistics */
+struct ble_ll_conn_stats
+{
+ uint32_t cant_set_sched;
+ uint32_t conn_ev_late;
+ uint32_t wfr_expirations;
+};
+struct ble_ll_conn_stats g_ble_ll_conn_stats;
+
+/* "Dummy" mbuf containing an "Empty PDU" */
+#define BLE_LL_DUMMY_EMPTY_PDU_SIZE \
+ ((sizeof(struct os_mbuf) + sizeof(struct os_mbuf_pkthdr) + 4) / 4)
+
+static uint32_t g_ble_ll_empty_pdu[BLE_LL_DUMMY_EMPTY_PDU_SIZE];
+
/**
* Calculates the number of used channels in the channel map
*
@@ -146,15 +257,45 @@ ble_ll_conn_calc_used_chans(uint8_t *chmap)
return used_channels;
}
+/**
+ * Free an allocated connection handle
+ *
+ * @param handle The connection handle to free.
+ */
+static void
+ble_ll_conn_handle_free(uint16_t handle)
+{
+ uint8_t bytepos;
+ uint8_t mask;
+ /* Make sure handle is valid */
+ assert(handle < BLE_LL_CONN_CFG_MAX_CONNS);
+ assert(g_ble_ll_conn_handles_out != 0);
+
+ /* Get byte position and bit position */
+ bytepos = handle / 8;
+ mask = 1 << (handle & 0x7);
+
+ assert((g_ble_ll_conn_handles[bytepos] & mask) != 0);
+
+ g_ble_ll_conn_handles[bytepos] &= ~mask;
+ --g_ble_ll_conn_handles_out;
+}
+
+/**
+ * Allocate a connection handle. This will allocate an unused connection
+ * handle.
+ *
+ * @return uint16_t
+ */
static uint16_t
-ble_ll_conn_get_unused_handle(void)
+ble_ll_conn_handle_alloc(void)
{
uint8_t bytepos;
uint8_t bitpos;
int handle;
- /* Keep track of total number so you can deny it! */
+ /* Make sure there is a handle that exists */
if (g_ble_ll_conn_handles_out == BLE_LL_CONN_CFG_MAX_CONNS) {
/* Handles can only be in range 0 to 0x0EFF */
return 0xFFFF;
@@ -267,14 +408,15 @@ ble_ll_conn_calc_access_addr(void)
}
/**
- * Determine the next data channel to be used for the connection.
+ * Determine data channel index to be used for the upcoming/current
+ * connection event
*
* @param conn
*
* @return uint8_t
*/
uint8_t
-ble_ll_next_data_channel(struct ble_ll_conn_sm *conn)
+ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn)
{
int i;
int j;
@@ -285,9 +427,11 @@ ble_ll_next_data_channel(struct ble_ll_conn_sm *conn)
uint8_t mask;
uint8_t usable_chans;
- /* Get next un mapped channel */
- curchan = (conn->last_unmapped_chan + conn->hop_inc) %
- BLE_PHY_NUM_DATA_CHANS;
+ /* Get next unmapped channel */
+ curchan = conn->last_unmapped_chan + conn->hop_inc;
+ if (curchan > BLE_PHY_NUM_DATA_CHANS) {
+ curchan -= BLE_PHY_NUM_DATA_CHANS;
+ }
/* Set the current unmapped channel */
conn->unmapped_chan = curchan;
@@ -324,6 +468,287 @@ ble_ll_next_data_channel(struct ble_ll_conn_sm *conn)
}
/**
+ * 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)
+{
+ int rc;
+ struct ble_ll_conn_sm *connsm;
+
+ connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
+ ble_ll_event_send(&connsm->conn_ev_end);
+ rc = BLE_LL_SCHED_STATE_DONE;
+ return rc;
+}
+
+/**
+ * Callback for connection wait for response timer.
+ *
+ * Context: Interrupt
+ *
+ * @param sch
+ *
+ * @return int
+ */
+static int
+ble_ll_conn_wfr_sched_cb(struct ble_ll_sched_item *sch)
+{
+ int rc;
+ struct ble_ll_conn_sm *connsm;
+
+ connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
+ if (connsm->rsp_rxd) {
+ /* For now just set to end time */
+ sch->next_wakeup = sch->end_time;
+ sch->sched_cb = ble_ll_conn_ev_end_sched_cb;
+ rc = BLE_LL_SCHED_STATE_RUNNING;
+ } else {
+ ble_ll_event_send(&connsm->conn_ev_end);
+ rc = BLE_LL_SCHED_STATE_DONE;
+ ++g_ble_ll_conn_stats.wfr_expirations;
+ }
+ return rc;
+}
+
+/**
+ * Schedule callback for start of connection event
+ *
+ * Context: Interrupt
+ *
+ * @param sch
+ *
+ * @return int
+ */
+static int
+ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch)
+{
+ int rc;
+ struct os_mbuf *m;
+ struct os_mbuf_pkthdr *pkthdr;
+ struct ble_ll_conn_sm *connsm;
+
+ /* Set current connection state machine */
+ connsm = (struct ble_ll_conn_sm *)sch->cb_arg;
+ g_ble_ll_conn_cur_sm = connsm;
+
+ /* Set LL state */
+ ble_ll_state_set(BLE_LL_STATE_CONNECTION);
+
+ /* Set channel */
+ rc = ble_phy_setchan(connsm->data_chan_index, connsm->access_addr,
+ connsm->crcinit);
+ assert(rc == 0);
+
+ if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
+ /* Get packet off transmit queue. If none there, what to do? */
+ pkthdr = STAILQ_FIRST(&connsm->conn_txq);
+ if (pkthdr) {
+ /* Remove from queue */
+ m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
+ STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
+ } else {
+ /* Send empty pdu */
+ m = (struct os_mbuf *)&g_ble_ll_empty_pdu;
+ }
+
+ /* WWW: must modify the header */
+
+ rc = ble_phy_tx(m, BLE_PHY_TRANSITION_NONE, BLE_PHY_TRANSITION_RX_TX);
+ if (!rc) {
+ /* Set next schedule wakeup to check for wait for response */
+ sch->next_wakeup = cputime_get32() +
+ cputime_usecs_to_ticks(XCVR_TX_START_DELAY_USECS +
+ ble_ll_pdu_tx_time_get(m->om_len) +
+ BLE_LL_IFS +
+ BLE_LL_WFR_USECS);
+ sch->sched_cb = ble_ll_conn_wfr_sched_cb;
+ rc = BLE_LL_SCHED_STATE_RUNNING;
+ } else {
+ /* Error transmitting! Put back on transmit queue */
+ STAILQ_INSERT_HEAD(&connsm->conn_txq, pkthdr, omp_next);
+
+ /* Inform LL task of connection event end */
+ ble_ll_event_send(&connsm->conn_ev_end);
+ rc = BLE_LL_SCHED_STATE_DONE;
+
+ /* XXX: Is there anything else we need to do on failure? */
+ }
+ } else {
+ rc = ble_phy_rx();
+ if (rc) {
+ /* XXX: what happens if this fails? */
+ }
+ }
+
+ /* XXX: set state to connection here? */
+
+ /* XXX: make sure we set the end time of the event (if needed) not sure
+ * it is for master role. Have to think about it.
+ */
+
+ /* XXX: The return code here tells the scheduler whether
+ * to use the next wakeup time or determines if the scheduled event is
+ over. */
+ return rc;
+}
+
+/**
+ * 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 {
+ /* XXX: account for window widening/drift */
+ sch->start_time = connsm->anchor_point -
+ cputime_usecs_to_ticks(XCVR_RX_SCHED_DELAY_USECS);
+
+ /* XXX: what to do for slave? Not sure how much to schedule here.
+ For now, just schedule entire connection interval */
+ usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS;
+ }
+ sch->end_time = connsm->anchor_point + cputime_usecs_to_ticks(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);
+ } 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;
+}
+
+/* WWW:
+ * -> deal with data channel index (calculation it).
+ * -> deal with slave latency .
+ */
+
+/**
+ * Called upon end of connection event
+ *
+ * Context: Link-layer task
+ *
+ * @param void *arg Pointer to connection state machine
+ *
+ */
+void
+ble_ll_conn_event_end(void *arg)
+{
+ uint16_t latency;
+ uint32_t itvl;
+ struct ble_ll_conn_sm *connsm;
+
+ /*
+ * XXX: if we received a response we can apply slave latency. I am not
+ * sure how this applies to the master. I guess the master could possibly
+ * keep sending each anchor if it does not receive a reply. Possible that
+ * slave receives master but master does not get reply. This would cause
+ * master to re-transmit every connection event even though slave was
+ * asleep.
+ */
+ connsm = (struct ble_ll_conn_sm *)arg;
+
+ /* 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->pkt_rxd) {
+ latency += connsm->slave_latency;
+ itvl = itvl * latency;
+ connsm->pkt_rxd = 0;
+ }
+ 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 */
+ 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;
+ }
+
+ /* XXX: window widening for slave */
+
+ /* Link-layer is in standby state now */
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+ /* Set current LL connection to NULL */
+ g_ble_ll_conn_cur_sm = NULL;
+
+ /* Schedule the next connection event */
+ ble_ll_conn_sched_set(connsm);
+}
+
+/**
+ * Connection supervision timer callback; means that the connection supervision
+ * timeout has been reached and we should perform the appropriate actions.
+ *
+ * Context: Interrupt (cputimer)
+ *
+ * @param arg Pointer to connection state machine.
+ */
+void
+ble_ll_conn_spvn_timer_cb(void *arg)
+{
+ struct ble_ll_conn_sm *connsm;
+
+ /*
+ * WWW: What should we do with the PHY here? We could be transmitting or
+ * receiving. Need to figure out what to do.
+ */
+
+ connsm = (struct ble_ll_conn_sm *)arg;
+ ble_ll_event_send(&connsm->conn_spvn_ev);
+}
+
+/**
* Initialize 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,
@@ -333,26 +758,30 @@ ble_ll_next_data_channel(struct ble_ll_conn_sm *conn)
static void
ble_ll_conn_sm_init(struct ble_ll_conn_sm *connsm, struct hci_create_conn *hcc)
{
+ struct ble_ll_conn_global_params *conn_params;
+
/* Reset event counter and last unmapped channel; get a handle */
connsm->last_unmapped_chan = 0;
- connsm->conn_event_cntr = 0;
- connsm->conn_handle = ble_ll_conn_get_unused_handle();
+ connsm->event_cntr = 0;
+ connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
+
+ /* We better have an unused handle or we are in trouble! */
+ connsm->conn_handle = ble_ll_conn_handle_alloc();
+ assert(connsm->conn_handle < BLE_LL_CONN_CFG_MAX_CONNS);
if (hcc != NULL) {
/* Must be master */
connsm->conn_role = BLE_LL_CONN_ROLE_MASTER;
- connsm->conn_tx_win_size = BLE_LL_CONN_CFG_TX_WIN_SIZE;
- connsm->conn_tx_win_off = BLE_LL_CONN_CFG_TX_WIN_OFF;
+ 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;
/* Hop increment is a random value between 5 and 16. */
connsm->hop_inc = (rand() % 12) + 5;
- /* Set slave latency, supervision timeout and connection interval */
- connsm->conn_slave_latency = hcc->conn_latency;
- connsm->conn_spvn_tmo = hcc->supervision_timeout;
- /* XXX: for now, just make connection interval equal to max */
- connsm->conn_itvl = hcc->conn_itvl_max;
+ /* Set slave latency and supervision timeout */
+ connsm->slave_latency = hcc->conn_latency;
+ connsm->supervision_tmo = hcc->supervision_timeout;
/* Set own address type and peer address if needed */
connsm->own_addr_type = hcc->own_addr_type;
@@ -361,11 +790,27 @@ ble_ll_conn_sm_init(struct ble_ll_conn_sm *connsm, struct hci_create_conn *hcc)
connsm->peer_addr_type = hcc->peer_addr_type;
}
- /* XXX: what to do with min/max connection event length? */
+ /* XXX: for now, just make connection interval equal to max */
+ connsm->conn_itvl = hcc->conn_itvl_max;
- /* XXX: for now, just set the channel map to all 1's. Needs to get
- set to default or initialized or something */
- connsm->num_used_chans = 37;
+ /* Check the min/max CE lengths are less than connection interval */
+ if (hcc->min_ce_len > (connsm->conn_itvl * 2)) {
+ connsm->min_ce_len = connsm->conn_itvl * 2;
+ } else {
+ connsm->min_ce_len = hcc->min_ce_len;
+ }
+
+ if (hcc->max_ce_len > (connsm->conn_itvl * 2)) {
+ connsm->max_ce_len = connsm->conn_itvl * 2;
+ } else {
+ connsm->max_ce_len = hcc->max_ce_len;
+ }
+
+ /*
+ * XXX: for now, just set the channel map to all 1's. Needs to get
+ * set to default or initialized or something
+ */
+ connsm->num_used_chans = BLE_PHY_NUM_DATA_CHANS;
memset(connsm->chanmap, 0xff, BLE_LL_CONN_CHMAP_LEN - 1);
connsm->chanmap[4] = 0x1f;
@@ -375,6 +820,45 @@ ble_ll_conn_sm_init(struct ble_ll_conn_sm *connsm, struct hci_create_conn *hcc)
} else {
connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE;
}
+
+ /* Initialize connection supervision timer */
+ cputime_timer_init(&connsm->conn_spvn_timer, ble_ll_conn_spvn_timer_cb,
+ connsm);
+
+ /* Calculate the next data channel */
+ connsm->data_chan_index = ble_ll_conn_calc_dci(connsm);
+
+ /* Initialize event */
+ connsm->conn_spvn_ev.ev_arg = connsm;
+ connsm->conn_spvn_ev.ev_queued = 0;
+ connsm->conn_spvn_ev.ev_type = BLE_LL_EVENT_CONN_SPVN_TMO;
+
+ /* Connection end event */
+ connsm->conn_ev_end.ev_arg = connsm;
+ connsm->conn_ev_end.ev_queued = 0;
+ connsm->conn_ev_end.ev_type = BLE_LL_EVENT_CONN_EV_END;
+
+ /* Initialize transmit queue */
+ STAILQ_INIT(&connsm->conn_txq);
+
+ /* XXX: 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 */
+ /* initialize data length mgmt */
+ conn_params = &g_ble_ll_conn_params;
+ connsm->max_tx_octets = conn_params->conn_init_max_tx_octets;
+ connsm->max_rx_octets = conn_params->supp_max_rx_octets;
+ connsm->max_tx_time = conn_params->conn_init_max_tx_octets;
+ connsm->max_rx_time = conn_params->supp_max_rx_time;
+ connsm->rem_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN;
+ connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN;
+ connsm->eff_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN;
+ connsm->eff_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN;
+ connsm->rem_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
+ connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
+ connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
+ connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
+
+ /* XXX: Controller notifies host of changes to effective tx/rx time/bytes*/
}
/**
@@ -383,15 +867,13 @@ ble_ll_conn_sm_init(struct ble_ll_conn_sm *connsm, struct hci_create_conn *hcc)
* @param status The BLE error code associated with the event
*/
static void
-ble_ll_conn_comp_event_send(uint8_t status)
+ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status)
{
uint8_t *evbuf;
- struct ble_ll_conn_sm *connsm;
if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_COMPLETE - 1)) {
evbuf = os_memblock_get(&g_hci_cmd_pool);
if (evbuf) {
- connsm = &g_ble_ll_conn_sm;
evbuf[0] = BLE_HCI_EVCODE_LE_META;
evbuf[1] = BLE_HCI_LE_CONN_COMPLETE_LEN;
evbuf[2] = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
@@ -402,17 +884,123 @@ ble_ll_conn_comp_event_send(uint8_t status)
evbuf[7] = connsm->peer_addr_type;
memcpy(evbuf + 8, connsm->peer_addr, BLE_DEV_ADDR_LEN);
htole16(evbuf + 14, connsm->conn_itvl);
- htole16(evbuf + 16, connsm->conn_slave_latency);
+ htole16(evbuf + 16, connsm->slave_latency);
evbuf[18] = connsm->master_sca;
}
- /* XXX: what to do if we fail to send event? */
ble_ll_hci_event_send(evbuf);
}
}
}
/**
+ * Called when a connection is terminated
+ *
+ * Context: Link Layer task.
+ *
+ * @param connsm
+ * @param ble_err
+ */
+static void
+ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
+{
+ struct os_mbuf *m;
+ struct os_mbuf_pkthdr *pkthdr;
+
+ /* XXX: stop any connection schedule timers we created */
+ /* XXX: make sure phy interrupts are off and all that. We want to
+ * make sure that if a scheduled event fires off here we dont care;
+ * we just need to clean up properly
+ */
+
+ /* Free all packets on transmit queue */
+ while (1) {
+ /* Get mbuf pointer from packet header pointer */
+ pkthdr = STAILQ_FIRST(&connsm->conn_txq);
+ if (!pkthdr) {
+ break;
+ }
+ STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
+
+ m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf));
+ os_mbuf_free(&g_mbuf_pool, m);
+ }
+
+ /* Remove scheduler events just in case */
+ ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_CONN, connsm);
+
+ /* Make sure events off queue and connection supervison timer stopped */
+ cputime_timer_stop(&connsm->conn_spvn_timer);
+ os_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_spvn_ev);
+ os_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end);
+
+ /* Connection state machine is now idle */
+ connsm->conn_state = BLE_LL_CONN_STATE_IDLE;
+
+ /* Set Link Layer state to standby */
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
+
+ /* Send connection complete event */
+ ble_ll_conn_comp_event_send(connsm, ble_err);
+
+ /* Free up the handle */
+ ble_ll_conn_handle_free(connsm->conn_handle);
+
+ /* Free the connection state machine */
+ os_memblock_put(&g_ble_ll_conn_pool, connsm);
+}
+
+/**
+ * Called when a connection has been created. This function will
+ * -> Set the connection state to created.
+ * -> Start the connection supervision timer
+ * -> Set the Link Layer state to connection.
+ * -> Send a connection complete event.
+ *
+ * See Section 4.5.2 Vol 6 Part B
+ *
+ * Context: Link Layer
+ *
+ * @param connsm
+ */
+static void
+ble_ll_conn_created(struct ble_ll_conn_sm *connsm)
+{
+ uint32_t usecs;
+
+ /* Set state to created */
+ connsm->conn_state = BLE_LL_CONN_STATE_CREATED;
+
+ /* Set supervision timeout */
+ usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS * 6;
+ cputime_timer_relative(&connsm->conn_spvn_timer, usecs);
+
+ /* Clear packet received flag and response rcvd flag*/
+ connsm->rsp_rxd = 0;
+ connsm->pkt_rxd = 0;
+
+ /* XXX: get real end timing. By this I mean the real packet rx end time
+ * For now, we will just use time we got here as the start and hope we hit
+ the tx window */
+
+ /* Set first connection event time */
+ usecs = 1250 + (connsm->tx_win_off * BLE_LL_CONN_TX_WIN_USECS);
+ if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
+ usecs += ble_ll_pdu_tx_time_get(BLE_CONNECT_REQ_PDU_LEN) + BLE_LL_IFS;
+ } else {
+ /* XXX: need to deal with drift/window widening here */
+ usecs += 0;
+ }
+ connsm->anchor_point = cputime_get32() + cputime_usecs_to_ticks(usecs);
+
+ /* Send connection complete event to inform host of connection */
+ ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS);
+
+ /* Start the scheduler for the first connection event */
+ ble_ll_conn_sched_set(connsm);
+}
+
+/**
* Update the connection request PDU with the address type and address of
* advertiser we are going to send connect request to.
*
@@ -488,11 +1076,11 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm)
dptr[4] = connsm->crcinit >> 16;
dptr[5] = connsm->crcinit >> 8;
dptr[6] = (uint8_t)connsm->crcinit;
- dptr[7] = connsm->conn_tx_win_size;
- htole16(dptr + 8, connsm->conn_tx_win_off);
+ dptr[7] = connsm->tx_win_size;
+ htole16(dptr + 8, connsm->tx_win_off);
htole16(dptr + 10, connsm->conn_itvl);
- htole16(dptr + 12, connsm->conn_slave_latency);
- htole16(dptr + 14, connsm->conn_spvn_tmo);
+ htole16(dptr + 12, connsm->slave_latency);
+ htole16(dptr + 14, connsm->supervision_tmo);
memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CONN_CHMAP_LEN);
dptr[21] = connsm->hop_inc | connsm->master_sca;
}
@@ -507,22 +1095,20 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm)
int
ble_ll_conn_create(uint8_t *cmdbuf)
{
+ int rc;
uint32_t spvn_tmo_msecs;
uint32_t min_spvn_tmo_msecs;
struct hci_create_conn ccdata;
struct hci_create_conn *hcc;
struct ble_ll_conn_sm *connsm;
- /* XXX: what happens if we have too many! Do something about this */
+ /* If we are already creating a connection we should leave */
+ if (g_ble_ll_conn_create_sm) {
+ return BLE_ERR_CMD_DISALLOWED;
+ }
- /*
- * XXX: right now, we only allow one connection, so if the connection
- * state machine is used we return error. Otherewise, we would only need
- * to check the scanner. If it is enabled, it means we are initiating.
- */
/* If already enabled, we return an error */
- connsm = &g_ble_ll_conn_sm;
- if (ble_ll_scan_enabled() || (connsm->conn_state != BLE_LL_CONN_STATE_IDLE)) {
+ if (ble_ll_scan_enabled()) {
return BLE_ERR_CMD_DISALLOWED;
}
@@ -591,12 +1177,19 @@ ble_ll_conn_create(uint8_t *cmdbuf)
return BLE_ERR_INV_HCI_CMD_PARMS;
}
+ /* Min/max connection event lengths */
hcc->min_ce_len = le16toh(cmdbuf + 21);
hcc->max_ce_len = le16toh(cmdbuf + 23);
if (hcc->min_ce_len > hcc->max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
+ /* Make sure we can accept a connection! */
+ connsm = (struct ble_ll_conn_sm *)os_memblock_get(&g_ble_ll_conn_pool);
+ if (connsm == NULL) {
+ return BLE_ERR_CONN_LIMIT;
+ }
+
/* Initialize the connection sm */
ble_ll_conn_sm_init(connsm, hcc);
@@ -604,7 +1197,15 @@ ble_ll_conn_create(uint8_t *cmdbuf)
ble_ll_conn_req_pdu_make(connsm);
/* Start scanning */
- return ble_ll_scan_initiator_start(hcc);
+ rc = ble_ll_scan_initiator_start(hcc);
+ if (rc) {
+ os_memblock_put(&g_ble_ll_conn_pool, connsm);
+ } else {
+ /* Set the connection state machine we are trying to create. */
+ g_ble_ll_conn_create_sm = connsm;
+ }
+
+ return rc;
}
/**
@@ -619,23 +1220,23 @@ int
ble_ll_conn_create_cancel(void)
{
int rc;
+ struct ble_ll_conn_sm *connsm;
/*
* If we receive this command and we have not got a connection
* create command, we have to return disallowed. The spec does not say
- * what happens if the connection has already been established.
+ * what happens if the connection has already been established. We
+ * return disallowed as well
*/
- if (ble_ll_scan_enabled()) {
- /* stop scanning */
+ connsm = g_ble_ll_conn_create_sm;
+ 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());
-
- /* XXX: what to do with connection state machine? */
-
- /* Send connection complete event */
- ble_ll_conn_comp_event_send(BLE_ERR_UNK_CONN_ID);
+ ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID);
rc = BLE_ERR_SUCCESS;
} else {
- /* If we have established connection or we are idle do not allow */
+ /* If we are not attempting to create a connection*/
rc = BLE_ERR_CMD_DISALLOWED;
}
@@ -649,11 +1250,12 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
int rc;
struct ble_ll_conn_sm *connsm;
- rc = 0;
- connsm = &g_ble_ll_conn_sm;
- if ((connsm->peer_addr_type == addr_type) &&
+ connsm = g_ble_ll_conn_create_sm;
+ if (connsm && (connsm->peer_addr_type == addr_type) &&
!memcmp(adva, connsm->peer_addr, BLE_DEV_ADDR_LEN)) {
rc = 1;
+ } else {
+ rc = 0;
}
return rc;
@@ -661,6 +1263,8 @@ ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva)
/**
* Send a connection requestion to an advertiser
+ *
+ * Context: Interrupt
*
* @param addr_type Address type of advertiser
* @param adva Address of advertiser
@@ -670,18 +1274,10 @@ ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva)
{
int rc;
struct os_mbuf *m;
- struct ble_ll_conn_sm *connsm;
m = ble_ll_scan_get_pdu();
ble_ll_conn_req_pdu_update(m, adva, addr_type);
rc = ble_phy_tx(m, BLE_PHY_TRANSITION_RX_TX, BLE_PHY_TRANSITION_NONE);
- if (!rc) {
- connsm = &g_ble_ll_conn_sm;
- connsm->peer_addr_type = addr_type;
- memcpy(connsm->peer_addr, adva, BLE_DEV_ADDR_LEN);
- connsm->conn_state = BLE_LL_CONN_STATE_CREATED;
- }
-
return rc;
}
@@ -694,30 +1290,42 @@ ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva)
* @param rxbuf
*/
void
-ble_ll_init_rx_pdu_proc(uint8_t pdu_type, uint8_t *rxbuf, uint8_t crcok)
+ble_ll_init_rx_pdu_proc(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
{
- struct ble_ll_scan_sm *scansm;
+ uint8_t addr_type;
struct ble_ll_conn_sm *connsm;
- /* XXX: Do I care what pdu type I receive? Not sure exactly how to
- deal with knowing a connection request was sent. */
+ /* Get the connection state machine we are trying to create */
+ connsm = g_ble_ll_conn_create_sm;
+ if (!connsm) {
+ return;
+ }
- /*
- * XXX: Not sure I like this but I will deal with it for now. Just
- * check the connection state machine. If state is created, we move
- * to the connected state.
- */
- connsm = &g_ble_ll_conn_sm;
- if (crcok && (connsm->conn_state == BLE_LL_CONN_STATE_CREATED)) {
- /* Stop scanning */
- scansm = ble_ll_scan_sm_get();
- ble_ll_scan_sm_stop(scansm);
+ /* If we have sent a connect request, we need to enter CONNECTION state*/
+ if (ble_hdr->crcok && (ble_hdr->flags & BLE_MBUF_HDR_F_CONN_REQ_TXD)) {
+ /* Set address of advertiser to which we are connecting. */
+ if (!ble_ll_scan_whitelist_enabled()) {
+ /*
+ * XXX: need to see if the whitelist tells us exactly what peer
+ * addr type we should use? Not sure it matters. If whitelisting
+ * is not used the peer addr and type already set
+ */
+ /* Get address type of advertiser */
+ if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
+ addr_type = BLE_ADDR_TYPE_RANDOM;
+ } else {
+ addr_type = BLE_ADDR_TYPE_PUBLIC;
+ }
- /* We are now in connection state */
- ble_ll_state_set(BLE_LL_STATE_CONNECTION);
+ connsm->peer_addr_type = addr_type;
+ memcpy(connsm->peer_addr, rxbuf + BLE_LL_PDU_HDR_LEN,
+ BLE_DEV_ADDR_LEN);
+ }
- /* Send connection complete event */
- ble_ll_conn_comp_event_send(BLE_ERR_SUCCESS);
+ /* Connection has been created. Stop scanning */
+ g_ble_ll_conn_create_sm = NULL;
+ ble_ll_scan_sm_stop(ble_ll_scan_sm_get());
+ ble_ll_conn_created(connsm);
} else {
/* We need to re-enable the PHY if we are in idle state */
if (ble_phy_state_get() == BLE_PHY_STATE_IDLE) {
@@ -786,6 +1394,7 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
}
/* Check filter policy */
+ ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
if (ble_ll_scan_whitelist_enabled()) {
/* Check if device is on whitelist. If not, leave */
if (!ble_ll_whitelist_match(adv_addr, addr_type)) {
@@ -793,7 +1402,6 @@ ble_ll_init_rx_pdu_end(struct os_mbuf *rxpdu)
}
/* Set BLE mbuf header flags */
- ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
ble_hdr->flags |= BLE_MBUF_HDR_F_DEVMATCH;
} else {
/* XXX: Resolvable? Deal with those */
@@ -806,6 +1414,9 @@ 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->flags |= BLE_MBUF_HDR_F_CONN_REQ_TXD;
+ }
}
return rc;
@@ -834,10 +1445,39 @@ ble_ll_init_rx_pdu_start(uint8_t pdu_type)
}
/**
+ * Connection supervision timeout. When called, it means that the connection
+ * supervision timeout has been reached. If reached, we end the connection.
+ *
+ * Context: Link Layer
+ *
+ * @param arg Pointer to connection state machine.
+ */
+void
+ble_ll_conn_spvn_timeout(void *arg)
+{
+ ble_ll_conn_end((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.
+ */
+void
+ble_ll_conn_rsp_rxd(void)
+{
+ if (g_ble_ll_conn_cur_sm) {
+ g_ble_ll_conn_cur_sm->rsp_rxd = 1;
+ }
+}
+
+/**
* Called when a device has received a connect request while advertising and
* the connect request has passed the advertising filter policy and is for
* us. This will start a connection in the slave role.
- *
+ *
+ * Context: Link Layer
+ *
* @param rxbuf Pointer to received PDU
*/
void
@@ -849,10 +1489,15 @@ ble_ll_conn_slave_start(uint8_t *rxbuf)
/* XXX: Should we error check the parameters? */
+ /* Allocate a connection. If none available, dont do anything */
+ connsm = (struct ble_ll_conn_sm *)os_memblock_get(&g_ble_ll_conn_pool);
+ if (!connsm) {
+ return;
+ }
+
/* Set the pointer at the start of the connection data */
dptr = rxbuf + BLE_LL_CONN_REQ_ADVA_OFF + BLE_DEV_ADDR_LEN;
- connsm = &g_ble_ll_conn_sm;
connsm->access_addr = le32toh(dptr);
crcinit = dptr[4];
crcinit <<= 16;
@@ -860,15 +1505,16 @@ ble_ll_conn_slave_start(uint8_t *rxbuf)
crcinit <<= 8;
crcinit |= dptr[6];
connsm->crcinit = crcinit;
- connsm->conn_tx_win_size = dptr[7];
- connsm->conn_tx_win_off = le16toh(dptr + 8);
+ connsm->tx_win_size = dptr[7];
+ connsm->tx_win_off = le16toh(dptr + 8);
connsm->conn_itvl = le16toh(dptr + 10);
- connsm->conn_slave_latency = le16toh(dptr + 12);
- connsm->conn_spvn_tmo = le16toh(dptr + 14);
+ connsm->slave_latency = le16toh(dptr + 12);
+ connsm->supervision_tmo = le16toh(dptr + 14);
memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CONN_CHMAP_LEN);
connsm->hop_inc = dptr[21] & 0x1F;
connsm->master_sca = dptr[21] >> 5;
+ /* XXX: might want to set this differently based on adv. filter policy! */
/* Set the address of device that we are connecting with */
memcpy(&connsm->peer_addr, rxbuf + BLE_LL_PDU_HDR_LEN, BLE_DEV_ADDR_LEN);
if (rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK) {
@@ -882,26 +1528,48 @@ ble_ll_conn_slave_start(uint8_t *rxbuf)
/* Need to initialize the connection state machine */
ble_ll_conn_sm_init(connsm, NULL);
- /* Set connection state to created */
- connsm->conn_state = BLE_LL_CONN_STATE_CREATED;
-
- /* Set state to connection */
- ble_ll_state_set(BLE_LL_STATE_CONNECTION);
-
- /* Send connection complete event */
- ble_ll_conn_comp_event_send(BLE_ERR_SUCCESS);
+ /* The connection has been created. */
+ ble_ll_conn_created(connsm);
}
-/* Initializet the connection module */
+/* Initialize the connection module */
void
ble_ll_conn_init(void)
{
int rc;
+ uint16_t maxbytes;
+ struct os_mbuf *m;
+ struct ble_ll_conn_global_params *conn_params;
/* Create connection memory pool */
rc = os_mempool_init(&g_ble_ll_conn_pool, BLE_LL_CONN_CFG_MAX_CONNS,
sizeof(struct ble_ll_conn_sm), &g_ble_ll_conn_buf,
"LLConnPool");
-
assert(rc == 0);
+
+ /* Initialize list of active conections */
+ SLIST_INIT(&g_ble_ll_conn_active_list);
+
+ /* Configure the global LL parameters */
+ conn_params = &g_ble_ll_conn_params;
+ maxbytes = BLE_LL_CFG_SUPP_MAX_RX_BYTES + BLE_LL_DATA_MAX_OVERHEAD;
+ conn_params->supp_max_rx_time = ble_ll_pdu_tx_time_get(maxbytes);
+ conn_params->supp_max_rx_octets = BLE_LL_CFG_SUPP_MAX_RX_BYTES;
+
+ maxbytes = BLE_LL_CFG_SUPP_MAX_TX_BYTES + BLE_LL_DATA_MAX_OVERHEAD;
+ conn_params->supp_max_tx_time = ble_ll_pdu_tx_time_get(maxbytes);
+ conn_params->supp_max_tx_octets = BLE_LL_CFG_SUPP_MAX_TX_BYTES;
+
+ maxbytes = BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES + BLE_LL_DATA_MAX_OVERHEAD;
+ conn_params->conn_init_max_tx_time = ble_ll_pdu_tx_time_get(maxbytes);
+ conn_params->conn_init_max_tx_octets = BLE_LL_CFG_SUPP_MAX_TX_BYTES;
+
+ /* Initialize dummy empty pdu */
+ m = (struct os_mbuf *)&g_ble_ll_empty_pdu;
+ m->om_data = (uint8_t *)&g_ble_ll_empty_pdu[0];
+ m->om_data += sizeof(struct os_mbuf) + sizeof(struct os_mbuf_pkthdr);
+ m->om_len = 2;
+ m->om_flags = OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR);
+ OS_MBUF_PKTHDR(m)->omp_len = 2;
}
+
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index aaeab1b..6e97f26 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -501,6 +501,15 @@ ble_ll_scan_win_end_cb(struct ble_ll_sched_item *sch)
return BLE_LL_SCHED_STATE_DONE;
}
+/**
+ * Schedule callback for the start of a scan window
+ *
+ * Context: Interrupt
+ *
+ * @param sch
+ *
+ * @return int
+ */
static int
ble_ll_scan_start_cb(struct ble_ll_sched_item *sch)
{
@@ -514,7 +523,7 @@ ble_ll_scan_start_cb(struct ble_ll_sched_item *sch)
scansm = (struct ble_ll_scan_sm *)sch->cb_arg;
/* Set channel */
- rc = ble_phy_setchan(scansm->scan_chan);
+ rc = ble_phy_setchan(scansm->scan_chan, 0, 0);
assert(rc == 0);
/* Start receiving */
@@ -549,7 +558,7 @@ ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm)
/* XXX: Stop any timers we may have started */
/* Remove any scheduled advertising items */
- ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_SCAN);
+ ble_ll_sched_rmv(BLE_LL_SCHED_TYPE_SCAN, NULL);
/* Disable whitelisting (just in case) */
ble_ll_whitelist_disable();
@@ -559,6 +568,10 @@ ble_ll_scan_sm_stop(struct ble_ll_scan_sm *scansm)
/* Count # of times stopped */
++g_ble_ll_scan_stats.scan_stops;
+
+ /* XXX: Not sure this is correct. The LL might not actually be scanning */
+ /* Set LL state to standby */
+ ble_ll_state_set(BLE_LL_STATE_STANDBY);
}
static struct ble_ll_sched_item *
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/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 d0b3920..e131dff 100644
--- a/net/nimble/controller/src/ble_ll_sched.c
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -141,14 +141,17 @@ ble_ll_sched_add(struct ble_ll_sched_item *sch)
}
/**
- * Remove a schedule item
+ * Remove a schedule item. You can use this function to:
+ * 1) Remove all schedule items of type 'sched_type' (cb_arg = NULL)
+ * 2) Remove schedule items of type 'sched_type' and matching callback args
+ *
*
* @param sched_type
*
* @return int
*/
int
-ble_ll_sched_rmv(uint8_t sched_type)
+ble_ll_sched_rmv(uint8_t sched_type, void *cb_arg)
{
os_sr_t sr;
struct ble_ll_sched_item *entry;
@@ -162,8 +165,10 @@ ble_ll_sched_rmv(uint8_t sched_type)
while (entry) {
next = TAILQ_NEXT(entry, link);
if (entry->sched_type == sched_type) {
- TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link);
- os_memblock_put(&g_ble_ll_sched_pool, entry);
+ if ((cb_arg == NULL) || (cb_arg == entry->cb_arg)) {
+ TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link);
+ os_memblock_put(&g_ble_ll_sched_pool, entry);
+ }
}
entry = next;
}
@@ -230,7 +235,7 @@ ble_ll_sched_init(void)
g_ble_ll_sched_mem, "ll_sched");
assert(err == OS_OK);
- /* Start cputimer for the scheduler */
+ /* Initialize cputimer for the scheduler */
cputime_timer_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL);
return err;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/controller/src/ble_ll_whitelist.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_whitelist.c b/net/nimble/controller/src/ble_ll_whitelist.c
index 1cb15e8..c4a0e04 100644
--- a/net/nimble/controller/src/ble_ll_whitelist.c
+++ b/net/nimble/controller/src/ble_ll_whitelist.c
@@ -40,7 +40,6 @@ ble_ll_whitelist_chg_allowed(void)
{
int rc;
- /* XXX: add initiating to this */
/*
* This command is not allowed if:
* -> advertising uses the whitelist and we are currently advertising.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/drivers/native/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/native/src/ble_phy.c b/net/nimble/drivers/native/src/ble_phy.c
index cf6ccbb..aa91a14 100644
--- a/net/nimble/drivers/native/src/ble_phy.c
+++ b/net/nimble/drivers/native/src/ble_phy.c
@@ -152,7 +152,7 @@ ble_phy_isr(void)
assert(g_ble_phy_data.rxpdu != NULL);
/* Call Link Layer receive start function */
- rc = ble_ll_rx_start(g_ble_phy_data.rxpdu);
+ rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
if (rc >= 0) {
/* XXX: set rx end enable isr */
} else {
@@ -349,7 +349,7 @@ ble_phy_txpwr_get(void)
* @return int 0: success; PHY error code otherwise
*/
int
-ble_phy_setchan(uint8_t chan)
+ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
{
assert(chan < BLE_PHY_NUM_CHANS);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/drivers/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/src/ble_phy.c b/net/nimble/drivers/nrf52/src/ble_phy.c
index cd5549d..43bde94 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -26,6 +26,7 @@
/*
* XXX: TODO
* 1) make phy rx start and end function pointers to call?
+ * 2) How to set access address for data channel pdu's and crcinit
*/
/* To disable all radio interrupts */
@@ -212,7 +213,7 @@ ble_phy_isr(void)
}
/* Call Link Layer receive start function */
- rc = ble_ll_rx_start(g_ble_phy_data.rxpdu);
+ rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
if (rc >= 0) {
if (rc > 0) {
/* We need to go from disabled to TXEN */
@@ -426,19 +427,6 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t beg_trans, uint8_t end_trans)
return BLE_PHY_ERR_RADIO_STATE;
}
- /* Select tx address */
- if (g_ble_phy_data.phy_chan < BLE_PHY_NUM_DATA_CHANS) {
- /* XXX: fix this */
- assert(0);
- NRF_RADIO->TXADDRESS = 0;
- NRF_RADIO->RXADDRESSES = 0;
- NRF_RADIO->CRCINIT = 0;
- } else {
- NRF_RADIO->TXADDRESS = 0;
- NRF_RADIO->RXADDRESSES = 1;
- NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
- }
-
/* Set radio transmit data pointer */
NRF_RADIO->PACKETPTR = (uint32_t)txpdu->om_data;
@@ -546,9 +534,10 @@ ble_phy_txpwr_get(void)
* @return int 0: success; PHY error code otherwise
*/
int
-ble_phy_setchan(uint8_t chan)
+ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit)
{
uint8_t freq;
+ uint32_t prefix;
assert(chan < BLE_PHY_NUM_CHANS);
@@ -573,6 +562,16 @@ ble_phy_setchan(uint8_t chan)
freq = (BLE_PHY_DATA_CHAN0_FREQ_MHZ - 2400) +
(BLE_PHY_CHAN_SPACING_MHZ * (chan + 1));
}
+
+ /* Configure logical address 1 and crcinit */
+ prefix = NRF_RADIO->PREFIX0;
+ prefix &= 0xffff00ff;
+ prefix |= ((access_addr >> 24) & 0xFF) << 8;
+ NRF_RADIO->BASE1 = (access_addr << 8) & 0xFFFFFF00;
+ NRF_RADIO->PREFIX0 = prefix;
+ NRF_RADIO->TXADDRESS = 1;
+ NRF_RADIO->RXADDRESSES = (1 << 1);
+ NRF_RADIO->CRCINIT = crcinit;
} else {
if (chan == 37) {
freq = BLE_PHY_CHAN_SPACING_MHZ;
@@ -583,6 +582,11 @@ ble_phy_setchan(uint8_t chan)
/* This advertising channel is at 2480 MHz */
freq = BLE_PHY_CHAN_SPACING_MHZ * 40;
}
+
+ /* Logical adddress 0 preconfigured */
+ NRF_RADIO->TXADDRESS = 0;
+ NRF_RADIO->RXADDRESSES = (1 << 0);
+ NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV;
}
/* Set the frequency and the data whitening initial value */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index 2b4fd36..138eec0 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -60,7 +60,7 @@ host_hci_le_cmd_send(uint16_t ocf, uint8_t len, void *cmddata)
}
rc = host_hci_cmd_send(cmd);
if (rc == 0) {
- host_hci_outstanding_opcode = opcode;
+ //host_hci_outstanding_opcode = opcode;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 8df8d9d..71229f2 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -37,6 +37,7 @@ extern struct os_mempool g_hci_os_event_pool;
* The BLE mbuf header contains the following:
* flags: bitfield with the following values
* 0x01: Set if there was a match on the whitelist
+ * 0x02: Set if a connect request was transmitted upon receiving pdu
* channel: The logical BLE channel PHY channel # (0 - 39)
* crcok: flag denoting CRC check passed (1) or failed (0).
* rssi: RSSI, in dBm.
@@ -50,7 +51,8 @@ struct ble_mbuf_hdr
};
/* Flag definitions */
-#define BLE_MBUF_HDR_F_DEVMATCH (0x01)
+#define BLE_MBUF_HDR_F_DEVMATCH (0x01)
+#define BLE_MBUF_HDR_F_CONN_REQ_TXD (0x02)
#define BLE_MBUF_HDR_PTR(om) \
(struct ble_mbuf_hdr *)((uint8_t *)om + sizeof(struct os_mbuf) + \
@@ -80,7 +82,7 @@ enum ble_error_codes
BLE_ERR_AUTH_FAIL = 5,
BLE_ERR_PINKEY_MISSING = 6,
BLE_ERR_MEM_CAPACITY = 7,
- BLE_ERR_CONN_TMO = 8,
+ BLE_ERR_CONN_SPVN_TMO = 8,
BLE_ERR_CONN_LIMIT = 9,
BLE_ERR_SYNCH_CONN_LIMIT = 10,
BLE_ERR_ACL_CONN_EXISTS = 11,
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/47dff3ec/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index db19665..9cbdcd8 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -30,7 +30,6 @@
/* Init all tasks */
volatile int tasks_initialized;
-int init_tasks(void);
/* Task 1 */
#define HOST_TASK_PRIO (1)
@@ -75,7 +74,7 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
#define BLETEST_CFG_SCAN_FILT_POLICY (BLE_HCI_SCAN_FILT_USE_WL)
/* BLETEST variables */
-#define BLETEST_STACK_SIZE (64)
+#define BLETEST_STACK_SIZE (256)
#define BLETEST_TASK_PRIO (HOST_TASK_PRIO + 1)
uint32_t g_next_os_time;
int g_bletest_state;
@@ -214,42 +213,6 @@ bletest_init_scanner(void)
}
}
-void
-host_task_handler(void *arg)
-{
- int rc;
-
- /* Init the console */
- rc = console_init(NULL);
- assert(rc == 0);
-
- /* Initialize host HCI */
- ble_hs_init(HOST_TASK_PRIO);
-
- /* Initialize the BLE LL */
- ble_ll_init();
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
- /* Initialize the advertiser */
- bletest_init_advertising();
-#endif
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
- /* Initialize the scanner */
- bletest_init_scanner();
-#endif
-
- /* Init bletest varibles */
- g_bletest_state = 0;
- g_next_os_time = os_time_get();
-
- /* We are initialized */
- console_printf("Nimble stack initialized");
-
- /* Call the host hci task */
- ble_hs_task_handler(arg);
-}
-
void
bletest_execute(void)
{
@@ -287,6 +250,11 @@ bletest_execute(void)
#endif
}
+/**
+ * Callback when BLE test timer expires.
+ *
+ * @param arg
+ */
void
bletest_timer_cb(void *arg)
{
@@ -297,18 +265,40 @@ bletest_timer_cb(void *arg)
os_callout_reset(&g_bletest_timer.cf_c, OS_TICKS_PER_SEC);
}
+/**
+ * BLE test task
+ *
+ * @param arg
+ */
void
bletest_task_handler(void *arg)
{
struct os_event *ev;
struct os_callout_func *cf;
+ /* We are initialized */
+ console_printf("Starting BLE test task");
+
+ /* Initialize eventq */
+ os_eventq_init(&g_bletest_evq);
+
/* Initialize the host timer */
os_callout_func_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb,
NULL);
- /* Initialize eventq */
- os_eventq_init(&g_bletest_evq);
+#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
+ /* Initialize the advertiser */
+ bletest_init_advertising();
+#endif
+
+#if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
+ /* Initialize the scanner */
+ bletest_init_scanner();
+#endif
+
+ /* Init bletest variables */
+ g_bletest_state = 0;
+ g_next_os_time = os_time_get();
bletest_timer_cb(NULL);
@@ -335,7 +325,7 @@ bletest_task_handler(void *arg)
*
* @return int 0 success; error otherwise.
*/
-int
+static int
init_tasks(void)
{
os_task_init(&bletest_task, "bletest", bletest_task_handler, NULL,
@@ -344,6 +334,12 @@ init_tasks(void)
tasks_initialized = 1;
+ /* Initialize host HCI */
+ ble_hs_init(HOST_TASK_PRIO);
+
+ /* Initialize the BLE LL */
+ ble_ll_init();
+
return 0;
}
@@ -410,6 +406,10 @@ main(void)
g_led_pin = LED_BLINK_PIN;
gpio_init_out(g_led_pin, 1);
+ /* Init the console */
+ rc = console_init(NULL);
+ assert(rc == 0);
+
/* Init tasks */
init_tasks();
[2/3] incubator-mynewt-larva git commit: Fix type in hal for cputime
Posted by we...@apache.org.
Fix type in hal for cputime
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/c7cc3d03
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/c7cc3d03
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/c7cc3d03
Branch: refs/heads/master
Commit: c7cc3d0355eba61bc0fc0196d5a1aba6e6162c97
Parents: 9504907
Author: wes3 <wi...@micosa.io>
Authored: Tue Nov 17 13:05:02 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Thu Nov 19 11:31:04 2015 -0800
----------------------------------------------------------------------
hw/hal/include/hal/hal_cputime.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c7cc3d03/hw/hal/include/hal/hal_cputime.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_cputime.h b/hw/hal/include/hal/hal_cputime.h
index 286736c..97d8709 100644
--- a/hw/hal/include/hal/hal_cputime.h
+++ b/hw/hal/include/hal/hal_cputime.h
@@ -170,7 +170,7 @@ void cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs);
*
* Stops a cputimer from running. The timer is removed from the timer queue
* and interrupts are disabled if no timers are left on the queue. Can be
- * called even if timer is running.
+ * called even if timer is not running.
*
* @param timer Pointer to cputimer to stop. Cannot be NULL.
*/
[3/3] incubator-mynewt-larva git commit: Remove erroneous debug
commit and add ble_ll_ctrl header file
Posted by we...@apache.org.
Remove erroneous debug commit and add ble_ll_ctrl header file
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/c9d16694
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/c9d16694
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/c9d16694
Branch: refs/heads/master
Commit: c9d16694d3080cfd7ef9225d4fdcf24e930a37ba
Parents: 47dff3e
Author: wes3 <wi...@micosa.io>
Authored: Thu Nov 19 11:33:10 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Thu Nov 19 11:33:10 2015 -0800
----------------------------------------------------------------------
.../controller/include/controller/ble_ll_ctrl.h | 190 +++++++++++++++++++
net/nimble/host/src/host_hci_cmd.c | 2 +-
2 files changed, 191 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c9d16694/net/nimble/controller/include/controller/ble_ll_ctrl.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_ctrl.h b/net/nimble/controller/include/controller/ble_ll_ctrl.h
new file mode 100644
index 0000000..044ed81
--- /dev/null
+++ b/net/nimble/controller/include/controller/ble_ll_ctrl.h
@@ -0,0 +1,190 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_BLE_LL_CTRL_
+#define H_BLE_LL_CTRL_
+
+/*
+ * LL CTRL PDU format
+ * -> Opcode (1 byte)
+ * -> Data (0 - 26 bytes)
+ */
+#define BLE_LL_CTRL_CONN_UPDATE_REQ (0)
+#define BLE_LL_CTRL_CHANNEL_MAP_REQ (1)
+#define BLE_LL_CTRL_TERMINATE_IND (2)
+#define BLE_LL_CTRL_ENC_REQ (3)
+#define BLE_LL_CTRL_ENC_RSP (4)
+#define BLE_LL_CTRL_START_ENC_REQ (5)
+#define BLE_LL_CTRL_START_ENC_RSP (6)
+#define BLE_LL_CTRL_UNKNOWN_RSP (7)
+#define BLE_LL_CTRL_FEATURE_REQ (8)
+#define BLE_LL_CTRL_FEATURE_RSP (9)
+#define BLE_LL_CTRL_PAUSE_ENC_REQ (10)
+#define BLE_LL_CTRL_PAUSE_ENC_RSP (11)
+#define BLE_LL_CTRL_VERSION_IND (12)
+#define BLE_LL_CTRL_REJECT_IND (13)
+#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (14)
+#define BLE_LL_CTRL_CONN_PARM_REQ (15)
+#define BLE_LL_CTRL_CONN_PARM_RSP (16)
+#define BLE_LL_CTRL_REJECT_IND_EXT (17)
+#define BLE_LL_CTRL_PING_REQ (18)
+#define BLE_LL_CTRL_PING_RSP (19)
+#define BLE_LL_CTRL_LENGTH_REQ (20)
+#define BLE_LL_CTRL_LENGTH_RSP (21)
+
+/* LL control connection update request */
+struct ble_ll_conn_upd_req
+{
+ uint8_t winsize;
+ uint16_t winoffset;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t timeout;
+ uint16_t instant;
+};
+#define BLE_LL_CTRL_CONN_UPD_REQ_LEN (11)
+
+/* LL control channel map request */
+struct ble_ll_chan_map_req
+{
+ uint8_t chmap[5];
+ uint16_t instant;
+};
+#define BLE_LL_CTRL_CHAN_MAP_LEN (7)
+
+/*
+ * LL control terminate ind
+ * -> error code (1 byte)
+ */
+#define BLE_LL_CTRL_TERMINATE_IND_LEN (1)
+
+/* LL control enc req */
+struct ble_ll_enc_req
+{
+ uint8_t rand[8];
+ uint16_t ediv;
+ uint8_t skdm[8];
+ uint32_t ivm;
+};
+
+#define BLE_LL_CTRL_ENC_REQ_LEN (22)
+
+/* LL control enc rsp */
+struct ble_ll_enc_rsp
+{
+ uint8_t skds[8];
+ uint32_t ivs;
+};
+
+#define BLE_LL_CTRL_ENC_RSP_LEN (12)
+
+/* LL control start enc req and start enc rsp have no data */
+#define BLE_LL_CTRL_START_ENC_LEN (0)
+
+/*
+ * LL control unknown response
+ * -> 1 byte which contains the unknown or un-supported opcode.
+ */
+#define BLE_LL_CTRL_UNK_RSP_LEN (1)
+
+/*
+ * LL control feature req and LL control feature rsp
+ * -> 8 bytes of data containing features supported by device.
+ */
+#define BLE_LL_CTRL_FEATURE_LEN (8)
+
+/* LL control pause enc req and pause enc rsp have no data */
+#define BLE_LL_CTRL_PAUSE_ENC_LEN (0)
+
+/*
+ * LL control version ind
+ * -> version (1 byte):
+ * Contains the version number of the bluetooth controller specification.
+ * -> comp_id (2 bytes)
+ * Contains the company identifier of the manufacturer of the controller.
+ * -> sub_ver_num: Contains a unique value for implementation or revision of
+ * the bluetooth controller.
+ */
+struct ble_ll_version_ind
+{
+ uint8_t ble_ctrlr_ver;
+ uint16_t company_id;
+ uint16_t sub_ver_num;
+};
+
+#define BLE_LL_CTRL_VERSION_IND_LEN (5)
+
+/*
+ * LL control reject ind
+ * -> error code (1 byte): contains reason why request was rejected.
+ */
+#define BLE_LL_CTRL_REJ_IND_LEN (1)
+
+/*
+ * LL control slave feature req
+ * -> 8 bytes of data containing features supported by device.
+ */
+#define BLE_LL_CTRL_SLAVE_FEATURE_REQ_LEN (8)
+
+/* LL control connection param req and connection param rsp */
+struct ble_ll_conn_params
+{
+ uint16_t interval_min;
+ uint16_t interval_max;
+ uint16_t latency;
+ uint16_t timeout;
+ uint16_t pref_periodicity;
+ uint16_t ref_conn_event_cnt;
+ uint16_t offset0;
+ uint16_t offset1;
+ uint16_t offset2;
+ uint16_t offset3;
+ uint16_t offset4;
+ uint16_t offset5;
+};
+
+#define BLE_LL_CTRL_CONN_PARAMS_LEN (24)
+
+/* LL control reject ind ext */
+struct ble_ll_reject_ind_ext
+{
+ uint8_t reject_opcode;
+ uint8_t err_code;
+};
+
+#define BLE_LL_CTRL_REJECT_IND_EXT_LEN (2)
+
+/* LL control ping req and ping rsp (contain no data) */
+#define BLE_LL_CTRL_PING_LEN (0)
+
+/*
+ * LL control length req and length rsp
+ * -> max_rx_bytes (2 bytes): defines connMaxRxOctets. Range 27 to 251
+ * -> max_rx_time (2 bytes): defines connMaxRxTime. Range 328 to 2120 usecs.
+ * -> max_tx_bytes (2 bytes): defines connMaxTxOctets. Range 27 to 251
+ * -> max_tx_time (2 bytes): defines connMaxTxTime. Range 328 to 2120 usecs.
+ */
+struct ble_ll_len_req
+{
+ uint16_t max_rx_bytes;
+ uint16_t max_rx_time;
+ uint16_t max_tx_bytes;
+ uint16_t max_tx_time;
+};
+
+#define BLE_LL_CTRL_LENGTH_REQ_LEN (8)
+
+#endif /* H_BLE_LL_CTRL_ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c9d16694/net/nimble/host/src/host_hci_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c
index 138eec0..2b4fd36 100644
--- a/net/nimble/host/src/host_hci_cmd.c
+++ b/net/nimble/host/src/host_hci_cmd.c
@@ -60,7 +60,7 @@ host_hci_le_cmd_send(uint16_t ocf, uint8_t len, void *cmddata)
}
rc = host_hci_cmd_send(cmd);
if (rc == 0) {
- //host_hci_outstanding_opcode = opcode;
+ host_hci_outstanding_opcode = opcode;
}
}