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/12/10 01:57:02 UTC

[1/2] incubator-mynewt-larva git commit: Implement data length change procedure. Now the advertiser does not stop advertising after 60 seconds. Advertising will end only if there is a connection

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 1d324a773 -> 05254c74c


Implement data length change procedure. Now the advertiser does not stop advertising after 60 seconds. Advertising will end only if there is a connection


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/05254c74
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/05254c74
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/05254c74

Branch: refs/heads/master
Commit: 05254c74ca8854d6d8f2d595ec35c2f17fed7770
Parents: acbd147
Author: wes3 <wi...@micosa.io>
Authored: Wed Dec 9 16:56:50 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Wed Dec 9 16:56:56 2015 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |  26 +-
 .../controller/include/controller/ble_ll_conn.h |  14 +-
 .../controller/include/controller/ble_ll_ctrl.h |   7 +-
 net/nimble/controller/src/ble_ll.c              |  48 ++-
 net/nimble/controller/src/ble_ll_conn.c         | 122 +++++--
 net/nimble/controller/src/ble_ll_ctrl.c         | 320 +++++++++++++++++--
 net/nimble/controller/src/ble_ll_hci.c          |   1 +
 net/nimble/host/src/host_dbg.c                  |   8 +-
 project/bletest/src/main.c                      |  19 +-
 9 files changed, 481 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/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 d532987..64ee545 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -32,6 +32,9 @@ struct ble_ll_obj
     /* Current Link Layer state */
     uint8_t ll_state;
 
+    /* Supported features */
+    uint8_t ll_supp_features;
+
     /* Task event queue */
     struct os_eventq ll_evq;
 
@@ -56,9 +59,11 @@ struct ble_ll_stats
     uint32_t hci_cmd_errs;
     uint32_t hci_events_sent;
     uint32_t bad_ll_state;
-    uint32_t rx_crc_ok;
-    uint32_t rx_crc_fail;
     uint32_t rx_bytes;
+    uint32_t rx_valid_adv_pdus;
+    uint32_t rx_invalid_adv_pdus;
+    uint32_t rx_adv_malformed_pkts;
+    uint32_t rx_adv_unk_pdu_type;
     uint32_t rx_adv_ind;
     uint32_t rx_adv_direct_ind;
     uint32_t rx_adv_nonconn_ind;
@@ -66,8 +71,17 @@ struct ble_ll_stats
     uint32_t rx_scan_rsps;
     uint32_t rx_connect_reqs;
     uint32_t rx_scan_ind;
-    uint32_t rx_unk_pdu;
-    uint32_t rx_malformed_pkts;
+    uint32_t rx_unk_pdus;
+    uint32_t rx_valid_data_pdus;
+    uint32_t rx_invalid_data_pdus;
+    uint32_t rx_ctrl_pdus;
+    uint32_t rx_l2cap_pdus;
+    uint32_t rx_malformed_ctrl_pdus;
+    uint32_t rx_bad_llid;
+    uint32_t tx_ctrl_pdus;
+    uint32_t tx_ctrl_bytes;
+    uint32_t tx_data_pdus;
+    uint32_t tx_data_bytes;
 };
 extern struct ble_ll_stats g_ble_ll_stats;
 
@@ -269,6 +283,9 @@ void ble_ll_wfr_enable(uint32_t cputime, ble_ll_wfr_func wfr_cb, void *arg);
 /* Disable wait for response timer */
 void ble_ll_wfr_disable(void);
 
+/* Read set of features supported by the Link Layer */
+uint8_t ble_ll_read_supp_features(void);
+
 /* 
  * XXX: temporary LL debug log. Will get removed once we transition to real
  * log
@@ -291,4 +308,5 @@ void ble_ll_log(uint8_t id, uint8_t arg0_8, uint8_t arg1_8, uint32_t arg0_32);
 #define ble_ll_log(m,n,o,p)
 #endif
 
+
 #endif /* H_LL_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/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 8aae9d3..6b61c6d 100644
--- a/net/nimble/controller/include/controller/ble_ll_conn.h
+++ b/net/nimble/controller/include/controller/ble_ll_conn.h
@@ -33,6 +33,12 @@
 #define BLE_MASTER_SCA_21_30_PPM        (6)
 #define BLE_MASTER_SCA_0_20_PPM         (7)
 
+/* Definitions for max rx/tx time/bytes for connections */
+#define BLE_LL_CONN_SUPP_TIME_MIN           (328)   /* usecs */
+#define BLE_LL_CONN_SUPP_TIME_MAX           (2120)  /* usecs */
+#define BLE_LL_CONN_SUPP_BYTES_MIN          (27)    /* bytes */
+#define BLE_LL_CONN_SUPP_BYTES_MAX          (251)   /* bytes */
+
 /* 
  * Length of empty pdu mbuf. Each connection state machine contains an
  * empty pdu since we dont want to allocate a full mbuf for an empty pdu
@@ -131,11 +137,12 @@ struct ble_ll_conn_sm
     /* empty pdu for connection */
     uint32_t conn_empty_pdu[BLE_LL_EMPTY_PDU_MBUF_SIZE];
 
-    /* LL control procedure timer */
-    struct os_callout_func ctrl_proc_timer;
+    /* LL control procedure response timer */
+    struct os_callout_func ctrl_proc_rsp_timer;
 };
 
 /* API */
+struct ble_ll_len_req;
 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);
@@ -152,5 +159,8 @@ void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok);
 void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len);
 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);
+void ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, 
+                                struct ble_ll_len_req *req);
+
 
 #endif /* H_BLE_LL_CONN_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/net/nimble/controller/include/controller/ble_ll_ctrl.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_ctrl.h b/net/nimble/controller/include/controller/ble_ll_ctrl.h
index 4a24cac..1382f8c 100644
--- a/net/nimble/controller/include/controller/ble_ll_ctrl.h
+++ b/net/nimble/controller/include/controller/ble_ll_ctrl.h
@@ -31,6 +31,7 @@
 #define BLE_LL_CTRL_PROC_CONN_PARAM_REQ (6)
 #define BLE_LL_CRTL_PROC_LE_PING        (7)
 #define BLE_LL_CTRL_PROC_DATA_LEN_UPD   (8)
+#define BLE_LL_CTRL_PROC_NUM            (9)
 #define BLE_LL_CTRL_PROC_IDLE           (255)
 
 /* 
@@ -61,6 +62,9 @@
 #define BLE_LL_CTRL_LENGTH_REQ          (20)
 #define BLE_LL_CTRL_LENGTH_RSP          (21)
 
+/* Maximum # of payload bytes in a LL control PDU */
+#define BLE_LL_CTRL_MAX_PAYLOAD         (26)
+
 /* LL control connection update request */
 struct ble_ll_conn_upd_req
 {
@@ -207,6 +211,7 @@ struct ble_ll_len_req
 void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc);
 void ble_ll_ctrl_proc_stop(struct ble_ll_conn_sm *connsm, int ctrl_proc);
 void ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om);
-
+void ble_ll_ctrl_datalen_chg_event(struct ble_ll_conn_sm *connsm);
+void ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm);
 
 #endif /* H_BLE_LL_CTRL_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/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 98006b3..667150c 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -52,9 +52,15 @@
  * 2) Need to figure out what to do with packets that we hand up that did
  * not pass the filter policy for the given state. Currently I count all
  * packets I think. Need to figure out what to do with this.
+ * 3) For the features defined, we need to conditionally compile code.
  * 
  */
 
+/* Configuration for supported features */
+#define BLE_LL_CFG_FEAT_DATA_LEN_EXT
+#undef BLE_LL_CFG_FEAT_LE_ENCRYPTION
+#undef BLE_LL_CFG_FEAT_EXT_REJECT_IND
+
 /* The global BLE LL data object */
 struct ble_ll_obj g_ble_ll_data;
 
@@ -140,7 +146,7 @@ ble_ll_count_rx_adv_pdus(uint8_t pdu_type)
         ++g_ble_ll_stats.rx_scan_ind;
         break;
     default:
-        ++g_ble_ll_stats.rx_unk_pdu;
+        ++g_ble_ll_stats.rx_adv_unk_pdu_type;
         break;
     }
 }
@@ -252,13 +258,15 @@ ble_ll_is_our_devaddr(uint8_t *addr, int addr_type)
 /**
  * ll pdu tx time get 
  *  
- * Returns the number of usecs it will take to transmit a PDU of length 'len' 
- * bytes. Each byte takes 8 usecs. 
+ * Returns the number of usecs it will take to transmit a PDU of length 'len'
+ * bytes. Each byte takes 8 usecs. This routine includes the LL overhead:
+ * preamble (1), access addr (4) and crc (3) for a total of 8 bytes.
  * 
- * @param len The number of PDU bytes to transmit
+ * @param len The number of PDU bytes to transmit. This includes both header
+ * and payload.
  * 
- * @return uint16_t The number of usecs it will take to transmit a PDU of 
- *                  length 'len' bytes. 
+ * @return uint16_t The number of usecs it will take to transmit a PDU of
+ *                  length 'len' bytes.
  */
 uint16_t
 ble_ll_pdu_tx_time_get(uint16_t len)
@@ -390,15 +398,14 @@ ble_ll_rx_pkt_in_proc(void)
         if (ble_hdr->crcok) {
             /* The total bytes count the PDU header and PDU payload */
             g_ble_ll_stats.rx_bytes += pkthdr->omp_len;
-            ++g_ble_ll_stats.rx_crc_ok;
-        } else {
-            ++g_ble_ll_stats.rx_crc_fail;
         }
 
         if (ble_hdr->channel < BLE_PHY_NUM_DATA_CHANS) {
             ble_ll_conn_rx_data_pdu(m, ble_hdr->crcok);
         } else {
             if (ble_hdr->crcok) {
+                ++g_ble_ll_stats.rx_valid_adv_pdus;
+
                 /* Get advertising PDU type */
                 pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
                 ble_ll_count_rx_adv_pdus(pdu_type);
@@ -429,6 +436,8 @@ ble_ll_rx_pkt_in_proc(void)
                     assert(0);
                     break;
                 }
+            } else {
+                ++g_ble_ll_stats.rx_invalid_adv_pdus;
             }
 
             /* Free the packet buffer */
@@ -638,7 +647,7 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, uint8_t crcok)
 
     /* If this is a malformed packet, just kill it here */
     if (badpkt) {
-        ++g_ble_ll_stats.rx_malformed_pkts;
+        ++g_ble_ll_stats.rx_adv_malformed_pkts;
         os_mbuf_free(rxpdu);
         return -1;
     }
@@ -758,6 +767,17 @@ ble_ll_event_send(struct os_event *ev)
 }
 
 /**
+ * Returns the features supported by the link layer
+ *
+ * @return uint8_t bitmask of supported features.
+ */
+uint8_t
+ble_ll_read_supp_features(void)
+{
+    return g_ble_ll_data.ll_supp_features;
+}
+
+/**
  * Initialize the Link Layer. Should be called only once 
  * 
  * @return int 
@@ -765,6 +785,7 @@ ble_ll_event_send(struct os_event *ev)
 int
 ble_ll_init(void)
 {
+    uint8_t features;
     struct ble_ll_obj *lldata;
 
     /* Get pointer to global data object */
@@ -800,6 +821,13 @@ ble_ll_init(void)
     /* Initialize the connection module */
     ble_ll_conn_init();
 
+    /* Set the supported features */
+    features = 0;
+#ifdef BLE_LL_CFG_FEAT_DATA_LEN_EXT
+    features |= BLE_LL_FEAT_DATA_LEN_EXT;
+#endif
+    lldata->ll_supp_features = features;
+
     /* 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/05254c74/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 548a116..c86b659 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -82,8 +82,8 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
 #define BLE_LL_CONN_CFG_OUR_SCA             (500)   /* in ppm */
 
 /* 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_SUPP_MAX_RX_BYTES        (251)
+#define BLE_LL_CFG_SUPP_MAX_TX_BYTES        (251)
 #define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES   (27)
 
 /* Roles */
@@ -96,10 +96,6 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
 #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)
 
@@ -149,16 +145,10 @@ struct ble_ll_conn_stats
     uint32_t slave_rxd_bad_conn_req_params;
     uint32_t slave_ce_failures;
     uint32_t rx_resent_pdus;
-    uint32_t data_pdu_rx_valid;
-    uint32_t data_pdu_rx_invalid;
-    uint32_t data_pdu_rx_bad_llid;
     uint32_t data_pdu_rx_dup;
-    uint32_t data_pdu_txd;
     uint32_t data_pdu_txg;
     uint32_t data_pdu_txf;
     uint32_t conn_req_txd;
-    uint32_t ctrl_pdu_rxd;
-    uint32_t l2cap_pdu_rxd;
 };
 struct ble_ll_conn_stats g_ble_ll_conn_stats;
 
@@ -573,7 +563,14 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int beg_transition)
             ble_ll_wfr_enable(wfr_time, ble_ll_conn_wait_txend, connsm);
         }
 
-        ++g_ble_ll_conn_stats.data_pdu_txd;
+        /* Increment packets transmitted */
+        if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
+            ++g_ble_ll_stats.tx_ctrl_pdus;
+            g_ble_ll_stats.tx_ctrl_bytes += OS_MBUF_PKTHDR(m)->omp_len;
+        } else {
+            ++g_ble_ll_stats.tx_data_pdus;
+            g_ble_ll_stats.tx_data_bytes += OS_MBUF_PKTHDR(m)->omp_len;
+        }
     }
 
     return rc;
@@ -860,13 +857,11 @@ ble_ll_conn_sm_start(struct ble_ll_conn_sm *connsm)
     connsm->cons_rxd_bad_crc = 0;
     connsm->last_rxd_sn = 1;
 
-    /* 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_tx_time = conn_params->conn_init_max_tx_time;
     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;
@@ -877,7 +872,19 @@ 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;
 
-    /* XXX: Controller notifies host of changes to effective tx/rx time/bytes*/
+    /* 
+     * 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);
@@ -916,6 +923,58 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status)
 }
 
 /**
+ * Called when a remotes data length parameters change. 
+ *  
+ * Context: Link Layer task 
+ *  
+ * @param connsm 
+ * @param req 
+ */
+void
+ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm, 
+                           struct ble_ll_len_req *req)
+{
+    int send_event;
+    uint16_t eff_time;
+    uint16_t eff_bytes;
+
+    /* Update parameters */
+    connsm->rem_max_rx_time = req->max_rx_time;
+    connsm->rem_max_tx_time = req->max_tx_time;
+    connsm->rem_max_rx_octets = req->max_rx_bytes;
+    connsm->rem_max_tx_octets = req->max_tx_bytes;
+
+    /* Assume no event sent */
+    send_event = 0;
+
+    /* See if effective times have changed */
+    eff_time = min(connsm->rem_max_rx_time, connsm->max_rx_time);
+    if (eff_time != connsm->eff_max_rx_time) {
+        connsm->eff_max_rx_time = eff_time;
+        send_event = 1;
+    }
+    eff_time = min(connsm->rem_max_tx_time, connsm->max_tx_time);
+    if (eff_time != connsm->eff_max_tx_time) {
+        connsm->eff_max_tx_time = eff_time;
+        send_event = 1;
+    }
+    eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_rx_octets);
+    if (eff_bytes != connsm->eff_max_rx_octets) {
+        connsm->eff_max_rx_octets = eff_bytes;
+        send_event = 1;
+    }
+    eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_tx_octets);
+    if (eff_bytes != connsm->eff_max_tx_octets) {
+        connsm->eff_max_tx_octets = eff_bytes;
+        send_event = 1;
+    }
+
+    if (send_event) {
+        ble_ll_ctrl_datalen_chg_event(connsm);
+    }
+}
+
+/**
  * Called when a connection is terminated 
  *  
  * Context: Link Layer task. 
@@ -942,7 +1001,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
     ble_ll_wfr_disable();
 
     /* Stop any control procedures that might be running */
-    os_callout_stop(&connsm->ctrl_proc_timer.cf_c);
+    os_callout_stop(&connsm->ctrl_proc_rsp_timer.cf_c);
 
     /* Remove from the active connection list */
     SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
@@ -1129,8 +1188,12 @@ ble_ll_conn_event_end(void *arg)
         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);
 
@@ -1225,6 +1288,8 @@ ble_ll_conn_req_pdu_make(struct ble_ll_conn_sm *connsm)
 
 /**
  * Process the HCI command to create a connection. 
+ *  
+ * Context: Link Layer task (HCI command processing) 
  * 
  * @param cmdbuf 
  * 
@@ -1658,7 +1723,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
 
     if (crcok) {
         /* Count valid received data pdus */
-        ++g_ble_ll_conn_stats.data_pdu_rx_valid;
+        ++g_ble_ll_stats.rx_valid_data_pdus;
 
         /* We better have a connection state machine */
         connsm = g_ble_ll_conn_cur_sm;
@@ -1676,7 +1741,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
             /* Check that the LLID is reasonable */
             if ((acl_hdr == 0) || 
                 ((acl_hdr == BLE_LL_LLID_DATA_START) && (acl_len == 0))) {
-                ++g_ble_ll_conn_stats.data_pdu_rx_bad_llid;
+                ++g_ble_ll_stats.rx_bad_llid;
                 goto conn_rx_data_pdu_end;
             }
 
@@ -1705,13 +1770,12 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
                 }
 
                 if (acl_hdr == BLE_LL_LLID_CTRL) {
-                    /* XXX: Process control frame! For now just free */
-                    ++g_ble_ll_conn_stats.ctrl_pdu_rxd;
+                    /* Process control frame! For now just free */
+                    ++g_ble_ll_stats.rx_ctrl_pdus;
                     ble_ll_ctrl_rx_pdu(connsm, rxpdu);
                 } else {
-
                     /* Count # of data frames */
-                    ++g_ble_ll_conn_stats.l2cap_pdu_rxd;
+                    ++g_ble_ll_stats.rx_l2cap_pdus;
 
                     /* NOTE: there should be at least two bytes available */
                     assert(OS_MBUF_LEADINGSPACE(rxpdu) >= 2);
@@ -1722,8 +1786,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
                     htole16(rxbuf, acl_hdr);
                     htole16(rxbuf + 2, acl_len);
                     ble_hs_rx_data(rxpdu);
-                    return;
                 }
+
+                /* NOTE: we dont free the mbuf since we handed it off! */
+                return;
             } else {
                 ++g_ble_ll_conn_stats.data_pdu_rx_dup;
             }
@@ -1731,7 +1797,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok)
             ++g_ble_ll_conn_stats.no_conn_sm;
         }
     } else {
-        ++g_ble_ll_conn_stats.data_pdu_rx_invalid;
+        ++g_ble_ll_stats.rx_invalid_data_pdus;
     }
 
     /* Free buffer */
@@ -2099,7 +2165,7 @@ ble_ll_conn_init(void)
      */
     connsm = &g_ble_ll_conn_sm[0];
     for (i = 0; i < BLE_LL_CONN_CFG_MAX_CONNS; ++i) {
-        connsm->conn_handle = i;
+        connsm->conn_handle = i + 1;
         STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe);
 
         /* Initialize empty pdu */
@@ -2128,6 +2194,6 @@ ble_ll_conn_init(void)
 
     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;
+    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/05254c74/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 25c77ba..b04a02f 100644
--- a/net/nimble/controller/src/ble_ll_ctrl.c
+++ b/net/nimble/controller/src/ble_ll_ctrl.c
@@ -26,27 +26,127 @@
 /* 
  * XXX: TODO
  *  1) Do I need to keep track of which procedures have already been done?
- *  Do I need to worry about repeating procedures?
- *  2) If we fail to get a LL control PDU we will probably need to know that
- *  right? Should I keep a procedure state variable? I could save memory
- *  by only using the low 4 bits of the current procedure.
- *  3) Probably create my own pool of control pdu's here. Dont need more
+ *     Do I need to worry about repeating procedures?
+ *  2) Should we create pool of control pdu's?. Dont need more
  *  than the # of connections and can probably deal with quite a few less
  *  if we have lots of connections.
  *  4) os_callout_func_init does not really need to be done every time I
  *  dont think. Do that once per connection when initialized?
  *  5) NOTE: some procedures are allowed to run while others are
  *      running!!! Fix this in the code
- *  6) Make sure we send data length change event to host.
- *  7) We need to start the control procedure for data length change!
- *  Deal with this.
  *  8) What about procedures that have been completed but try to restart?
- *  9) How do I deal with control procedures that are pending? What happens
- *  if we cant get an mbuf? There will be pending control procedures without
- *  one running. WHen/how do I deal with that?
- *  10) Make sure that we stop the data length update procedure if we receive
- *  a response. Need to look at that.
+ *  12) NOTE: there is a supported features procedure. However, in the case
+ *  of data length extension, if the receiving device does not understand
+ *  the pdu or it does not support data length extension, the LL_UNKNOWN_RSP
+ *  pdu is sent. That needs to be processed...
+ *  14) Will I need to know which procedures actually completed?
+ *  15) We are supposed to remember when we do the data length update proc if
+ *  the device sent us an unknown rsp. We should not send it another len req.
+ *  Implement this.
+ *  16) Remember: some procedures dont have timeout rules.
+ *  17) remember to stop procedure when rsp received.
+ *  18) Says that we should reset procedure timer whenever a LL control pdu
+ *  is queued for transmission. I dont get it... do some procedures send
+ *  multiple packets? I guess so.
+ *  19) How to count control pdus sent. DO we count enqueued + sent, or only
+ *  sent (actually attempted to tx). Do we count failures? How?
+ * 
+ */
+
+/* XXX: Improvements
+ * 1) We can inititalize the procedure timer once per connection state machine
+ */
+
+/* Checks if a particular control procedure is running */
+#define IS_PENDING_CTRL_PROC_M(sm, proc) (sm->pending_ctrl_procs & (1 << proc))
+
+static int
+ble_ll_ctrl_chk_supp_bytes(uint16_t bytes)
+{
+    int rc;
+
+    if ((bytes < BLE_LL_CONN_SUPP_BYTES_MIN) || 
+        (bytes > BLE_LL_CONN_SUPP_BYTES_MAX)) {
+        rc = 0;
+    } else {
+        rc = 1;
+    }
+
+    return rc;
+}
+
+static int
+ble_ll_ctrl_chk_supp_time(uint16_t t)
+{
+    int rc;
+
+    if ((t < BLE_LL_CONN_SUPP_TIME_MIN) || (t > BLE_LL_CONN_SUPP_TIME_MAX)) {
+        rc = 0;
+    } else {
+        rc = 1;
+    }
+
+    return rc;
+}
+
+static int
+ble_ll_ctrl_len_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
+{
+    int rc;
+    struct ble_ll_len_req ctrl_req;
+
+    /* Extract parameters and check if valid */
+    ctrl_req.max_rx_bytes = le16toh(dptr + 3); 
+    ctrl_req.max_rx_time = le16toh(dptr + 5);
+    ctrl_req.max_tx_bytes = le16toh(dptr + 7);
+    ctrl_req.max_tx_time = le16toh(dptr + 9);
+
+    if (!ble_ll_ctrl_chk_supp_bytes(ctrl_req.max_rx_bytes) ||
+        !ble_ll_ctrl_chk_supp_bytes(ctrl_req.max_tx_bytes) ||
+        !ble_ll_ctrl_chk_supp_time(ctrl_req.max_tx_time) ||
+        !ble_ll_ctrl_chk_supp_time(ctrl_req.max_rx_time)) {
+        rc = 1;
+    } else {
+        /* Update the connection with the new parameters */
+        ble_ll_conn_datalen_update(connsm, &ctrl_req);
+        rc = 0;
+    }
+
+    return rc;
+}
+
+/**
+ * Called to process and UNKNOWN_RSP LL control packet.
+ * 
+ * Context: Link Layer Task 
+ *  
+ * @param dptr 
  */
+static void
+ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
+{
+    uint8_t ctrl_proc;
+    uint8_t opcode;
+
+    /* Get opcode of unknown LL control frame */
+    opcode = dptr[3];
+
+    /* Convert opcode to control procedure id */
+    switch (opcode) {
+    case BLE_LL_CTRL_LENGTH_REQ:
+        ctrl_proc = BLE_LL_CTRL_PROC_DATA_LEN_UPD;
+        break;
+    default:
+        ctrl_proc = BLE_LL_CTRL_PROC_NUM;
+        break;
+    }
+
+    /* If we are running this one currently, stop it */
+    if (connsm->cur_ctrl_proc == ctrl_proc) {
+        /* Stop the control procedure */
+        ble_ll_ctrl_proc_stop(connsm, ctrl_proc);
+    }
+}
 
 /**
  * Send a data length change event for a connection to the host.
@@ -75,6 +175,24 @@ ble_ll_ctrl_datalen_chg_event(struct ble_ll_conn_sm *connsm)
 }
 
 /**
+ * Create a link layer length request or length response PDU. 
+ *  
+ * NOTE: this function does not set the LL data pdu header nor does it 
+ * set the opcode in the buffer. 
+ * 
+ * @param connsm 
+ * @param dptr: Pointer to where control pdu payload starts
+ */
+static void
+ble_ll_ctrl_datalen_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
+{
+    htole16(dptr + 3, connsm->max_rx_octets);
+    htole16(dptr + 5, connsm->max_rx_time);
+    htole16(dptr + 7, connsm->max_tx_octets);
+    htole16(dptr + 9, connsm->max_tx_time);
+}
+
+/**
  * Callback when LL control procedure times out (for a given connection). If 
  * this is called, it means that we need to end the connection because it 
  * has not responded to a LL control request. 
@@ -84,7 +202,7 @@ ble_ll_ctrl_datalen_chg_event(struct ble_ll_conn_sm *connsm)
  * @param arg Pointer to connection state machine.
  */
 void
-ble_ll_ctrl_proc_timer_cb(void *arg)
+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);
@@ -115,12 +233,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
         case BLE_LL_CTRL_PROC_DATA_LEN_UPD:
             len = BLE_LL_CTRL_LENGTH_REQ_LEN;
             opcode = BLE_LL_CTRL_LENGTH_REQ;
-            htole16(dptr + 3, connsm->max_rx_octets);
-            htole16(dptr + 5, connsm->max_rx_time);
-            htole16(dptr + 7, connsm->max_tx_octets);
-            htole16(dptr + 9, connsm->max_tx_time);
-            om->om_len = BLE_LL_CTRL_LENGTH_REQ_LEN + BLE_LL_PDU_HDR_LEN;
-            OS_MBUF_PKTHDR(om)->omp_len = om->om_len;
+            ble_ll_ctrl_datalen_upd_make(connsm, dptr);
             break;
         default:
             assert(0);
@@ -128,9 +241,12 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
         }
 
         /* Set llid, length and opcode */
+        ++len;
         dptr[0] = BLE_LL_LLID_CTRL;
         dptr[1] = len;
         dptr[2] = opcode;
+        om->om_len = len + BLE_LL_PDU_HDR_LEN;
+        OS_MBUF_PKTHDR(om)->omp_len = om->om_len;
     }
 
     return om;
@@ -138,6 +254,8 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
 
 /**
  * Stops the LL control procedure indicated by 'ctrl_proc'. 
+ *  
+ * Context: Link Layer task 
  * 
  * @param connsm 
  * @param ctrl_proc 
@@ -146,17 +264,21 @@ void
 ble_ll_ctrl_proc_stop(struct ble_ll_conn_sm *connsm, int ctrl_proc)
 {
     if (connsm->cur_ctrl_proc == ctrl_proc) {
-        os_callout_stop(&connsm->ctrl_proc_timer.cf_c);
+        os_callout_stop(&connsm->ctrl_proc_rsp_timer.cf_c);
         connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_IDLE;
         connsm->pending_ctrl_procs &= ~(1 << ctrl_proc);
     }
-    /* XXX: if there are more pending ones, what do we do? */
+
+    /* If there are others, start them */
+    ble_ll_ctrl_chk_proc_start(connsm);
 }
 
 /**
  * Called to start a LL control procedure. We always set the control 
  * procedure pending bit even if the input control procedure has been 
  * initiated. 
+ *  
+ * Context: Link Layer task. 
  * 
  * @param connsm Pointer to connection state machine.
  */
@@ -176,14 +298,14 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc)
             /* Add packet to transmit queue of connection */
             ble_ll_conn_enqueue_pkt(connsm, om);
 
-            /* Initialize the host timer */
-            os_callout_func_init(&connsm->ctrl_proc_timer, 
+            /* Initialize the procedure response timeout */
+            os_callout_func_init(&connsm->ctrl_proc_rsp_timer, 
                                  &g_ble_ll_data.ll_evq, 
-                                 ble_ll_ctrl_proc_timer_cb, 
+                                 ble_ll_ctrl_proc_rsp_timer_cb, 
                                  connsm);
 
             /* Re-start the timer. Control procedure timeout is 40 seconds */
-            os_callout_reset(&connsm->ctrl_proc_timer.cf_c, 
+            os_callout_reset(&connsm->ctrl_proc_rsp_timer.cf_c, 
                              OS_TICKS_PER_SEC * 40);
         }
     }
@@ -193,9 +315,37 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc)
 }
 
 /**
- * Called when the Link Layer receives a LL control PDU. 
+ * Called to determine if we need to start a LL control procedure for the given 
+ * connection. 
+ *  
+ * Context: Link Layer 
  *  
- * NOTE: the calling function frees the mbuf! 
+ * @param connsm Pointer to connection state machine.
+ */
+void
+ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm)
+{
+    int i;
+
+    /* If there is a running procedure or no pending, do nothing */
+    if ((connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_IDLE) &&
+        (connsm->pending_ctrl_procs != 0)) {
+        /* 
+         * The specification says there is no priority to control procedures
+         * so just start from the first one for now.
+         */
+        for (i = 0; i < BLE_LL_CTRL_PROC_NUM; ++i) {
+            if (IS_PENDING_CTRL_PROC_M(connsm, i)) {
+                ble_ll_ctrl_proc_start(connsm, i);
+                break;
+            }
+        }
+    }
+}
+
+/**
+ * Called when the Link Layer receives a LL control PDU. This function 
+ * must either free the received pdu or re-use it for the response. 
  *  
  * Context: Link Layer 
  * 
@@ -205,6 +355,116 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc)
 void
 ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
 {
-    /* XXX: implement */
-}
+    uint8_t features;
+    uint8_t len;
+    uint8_t opcode;
+    uint8_t *dptr;
+
+    /* XXX: where do we validate length received and packet header length?
+     * do this in LL task when received. Someplace!!! What I mean
+     * is we should validate the over the air length with the mbuf length.
+       Should the PHY do that???? */
+
+    /* Get length and opcode from PDU */
+    dptr = om->om_data;
+    len = dptr[1];
+    opcode = dptr[2];
 
+    /* opcode must be good */
+    if ((opcode > BLE_LL_CTRL_LENGTH_RSP) || (len < 1) || 
+        (len > BLE_LL_CTRL_MAX_PAYLOAD)) {
+        goto rx_malformed_ctrl;
+    }
+
+    /* Subtract the opcode from the length */
+    --len;
+
+    switch (opcode) {
+    case BLE_LL_CTRL_LENGTH_REQ:
+        /* Check length */
+        if (len != BLE_LL_CTRL_LENGTH_REQ_LEN) {
+            goto rx_malformed_ctrl;
+        }
+
+        /* Check parameters for validity */
+        features = ble_ll_read_supp_features();
+        if (features & BLE_LL_FEAT_DATA_LEN_EXT) {
+            /* Extract parameters and check if valid */
+            if (ble_ll_ctrl_len_proc(connsm, dptr)) {
+                goto rx_malformed_ctrl;
+            }
+
+            /* 
+             * If we have not started this procedure ourselves and it is
+             * pending, no need to perform it.
+             */
+            if ((connsm->cur_ctrl_proc != BLE_LL_CTRL_PROC_DATA_LEN_UPD) &&
+                IS_PENDING_CTRL_PROC_M(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD)) {
+                connsm->pending_ctrl_procs &= ~BLE_LL_CTRL_PROC_DATA_LEN_UPD;
+            }
+
+            /* Send a response */
+            opcode = BLE_LL_CTRL_LENGTH_RSP;
+            ble_ll_ctrl_datalen_upd_make(connsm, dptr);
+        } else {
+            /* XXX: construct unknown pdu */
+            opcode = BLE_LL_CTRL_UNKNOWN_RSP;
+            len = BLE_LL_CTRL_UNK_RSP_LEN;
+            dptr[3] = BLE_LL_CTRL_LENGTH_REQ;
+        }
+        break;
+    case BLE_LL_CTRL_LENGTH_RSP:
+        /* Check length (response length same as request length) */
+        if (len != BLE_LL_CTRL_LENGTH_REQ_LEN) {
+            goto rx_malformed_ctrl;
+        }
+
+        /* 
+         * According to specification, we should only process this if we
+         * asked for it.
+         */
+        if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_DATA_LEN_UPD) {
+            /* Process the received data */
+            if (ble_ll_ctrl_len_proc(connsm, dptr)) {
+                goto rx_malformed_ctrl;
+            }
+
+            /* Stop the control procedure */
+            ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
+        }
+        opcode = 255;
+        break;
+    case BLE_LL_CTRL_UNKNOWN_RSP:
+        /* Check length (response length same as request length) */
+        if (len != BLE_LL_CTRL_UNK_RSP_LEN) {
+            goto rx_malformed_ctrl;
+        }
+
+        ble_ll_ctrl_proc_unk_rsp(connsm, dptr);
+        opcode = 255;
+        break;
+    default:
+        /* XXX: this is an un-implemented control procedure. What to do? */
+        opcode = 255;
+        break;
+    }
+
+    /* Free mbuf or send response */
+    if (opcode == 255) {
+        os_mbuf_free(om);
+    } else {
+        ++len;
+        dptr[0] = BLE_LL_LLID_CTRL;
+        dptr[1] = len;
+        dptr[2] = opcode;
+        om->om_len = len + BLE_LL_PDU_HDR_LEN;
+        OS_MBUF_PKTHDR(om)->omp_len = om->om_len;
+        ble_ll_conn_enqueue_pkt(connsm, om);
+    }
+    return;
+
+rx_malformed_ctrl:
+    os_mbuf_free(om);
+    ++g_ble_ll_stats.rx_malformed_ctrl_pdus;
+    return;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c
index c162227..9fe7c9e 100644
--- a/net/nimble/controller/src/ble_ll_hci.c
+++ b/net/nimble/controller/src/ble_ll_hci.c
@@ -118,6 +118,7 @@ ble_ll_hci_le_read_local_features(uint8_t *rspbuf, uint8_t *rsplen)
 {    
     /* Add list of supported features. */
     memset(rspbuf, 0, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN);
+    rspbuf[0] = ble_ll_read_supp_features();
     *rsplen = BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN;
     return BLE_ERR_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/net/nimble/host/src/host_dbg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_dbg.c b/net/nimble/host/src/host_dbg.c
index b71677c..736a719 100644
--- a/net/nimble/host/src/host_dbg.c
+++ b/net/nimble/host/src/host_dbg.c
@@ -77,7 +77,13 @@ host_hci_dbg_le_event_disp(uint8_t subev, uint8_t len, uint8_t *evdata)
             console_printf("LE connection complete. FAIL (status=%u)\n",status);
         }
         break;
-
+    case BLE_HCI_LE_SUBEV_DATA_LEN_CHG:
+        console_printf("Data Length Change. handle=%u max_tx_bytes=%u "
+                       "max_tx_time=%u max_rx_bytes=%u max_rx_time=%u\n",
+                       le16toh(evdata), le16toh(evdata + 2), 
+                       le16toh(evdata + 4), le16toh(evdata + 6),
+                       le16toh(evdata + 8));
+        break;
     default:
         console_printf("\tUnknown LE event\n");
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/05254c74/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index 0dca7b5..6fbe3cd 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -62,7 +62,7 @@ os_membuf_t g_mbuf_buffer[MBUF_MEMPOOL_SIZE];
 #define BLETEST_ROLE_ADVERTISER         (0)
 #define BLETEST_ROLE_SCANNER            (1)
 #define BLETEST_ROLE_INITIATOR          (2)
-#define BLETEST_CFG_ROLE                (BLETEST_ROLE_ADVERTISER)
+#define BLETEST_CFG_ROLE                (BLETEST_ROLE_INITIATOR)
 #define BLETEST_CFG_FILT_DUP_ADV        (0)
 #define BLETEST_CFG_ADV_ITVL            (500000 / BLE_HCI_ADV_ITVL)
 #define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_IND
@@ -267,14 +267,9 @@ bletest_execute(void)
     int rc;
 
 #if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-    /* Enable advertising */
+    /*  */
     if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-        if (g_bletest_state) {
-            rc = host_hci_cmd_le_set_adv_enable(0);
-            host_hci_outstanding_opcode = 0;
-            assert(rc == 0);
-            g_bletest_state = 0;
-        } else {
+        if (!g_bletest_state) {
             rc = host_hci_cmd_le_set_adv_enable(1);
             host_hci_outstanding_opcode = 0;
             assert(rc == 0);
@@ -328,6 +323,8 @@ bletest_timer_cb(void *arg)
 void
 bletest_task_handler(void *arg)
 {
+    int rc;
+    uint64_t event_mask;
     struct os_event *ev;
     struct os_callout_func *cf;
 
@@ -356,6 +353,12 @@ bletest_task_handler(void *arg)
     bletest_init_initiator();
 #endif
 
+    /* Set the event mask we want to display */
+    event_mask = 0x7FF;
+    rc = host_hci_cmd_le_set_event_mask(event_mask);
+    assert(rc == 0);
+    host_hci_outstanding_opcode = 0;
+
     /* Init bletest variables */
     g_bletest_state = 0;
     g_next_os_time = os_time_get();



[2/2] incubator-mynewt-larva git commit: Get additional 32K of RAM on nrf52. See errata #33 and #34

Posted by we...@apache.org.
Get additional 32K of RAM on nrf52. See errata #33 and #34


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/acbd147d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/acbd147d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/acbd147d

Branch: refs/heads/master
Commit: acbd147dae0fe9f0ac90b81160042b002094ad6b
Parents: 1d324a7
Author: wes3 <wi...@micosa.io>
Authored: Wed Dec 9 11:09:54 2015 -0800
Committer: wes3 <wi...@micosa.io>
Committed: Wed Dec 9 16:56:56 2015 -0800

----------------------------------------------------------------------
 hw/bsp/nrf52pdk/nrf52pdk.ld | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/acbd147d/hw/bsp/nrf52pdk/nrf52pdk.ld
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52pdk/nrf52pdk.ld b/hw/bsp/nrf52pdk/nrf52pdk.ld
index 8be5b6a..144ea23 100755
--- a/hw/bsp/nrf52pdk/nrf52pdk.ld
+++ b/hw/bsp/nrf52pdk/nrf52pdk.ld
@@ -33,10 +33,17 @@
  */
 OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
 
+/* 
+ * NOTE: This linker script is for version 1.0 of the nrf52. See
+ * errata #33 and #34 on nordic infocenter website for details. This errata
+ * causes us to allocate a memory regision we call "CODE_RAM" so that we can
+ * access the full 64K RAM provided by the chip.
+ */ 
 MEMORY
 {
   FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
-  RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x8000
+  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000
+  CODE_RAM (rwx) : ORIGIN = 0x8000000, LENGTH = 0x8000
 }
 
 /* Linker script to place sections and symbol values. Should be used together
@@ -168,20 +175,20 @@ SECTIONS
         __bss_end__ = .;
     } > RAM
 
-    /* Heap starts after BSS */
-    __HeapBase = .;
-
     /* .stack_dummy section doesn't contains any symbols. It is only
      * used for linker to calculate size of stack sections, and assign
      * values to stack symbols later */
     .stack_dummy (COPY):
     {
         *(.stack*)
-    } > RAM
-
-    /* Set stack top to end of RAM, and stack limit move down by
-     * size of stack_dummy section */
-    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+    } > CODE_RAM
+
+    /* 
+     * Place heap and stack in CODE_RAM. Heap is at start, stack is at the
+     * top and stack limit is the bottom of the stack.
+     */
+    __HeapBase = ORIGIN(CODE_RAM);
+    __StackTop = ORIGIN(CODE_RAM) + LENGTH(CODE_RAM);
     __StackLimit = __StackTop - SIZEOF(.stack_dummy);
     PROVIDE(__stack = __StackTop);