Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master f77968f01 -> f95ce4fe1


Fix issues with Link Layer fragmentation. We now support (fully) the data 
length extension feature and fragmentation of ACL data packets inside the 
controller


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

Branch: refs/heads/master
Commit: f95ce4fe1d72dd5b1c3e9096e0651984587050ce
Parents: f77968f
Author: wes3 <w...@micosa.io>
Authored: Wed Jan 6 09:07:25 2016 -0800
Committer: wes3 <w...@micosa.io>
Committed: Wed Jan 6 09:07:31 2016 -0800

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |  16 +-
 net/nimble/controller/src/ble_ll.c              |  38 ++---
 net/nimble/controller/src/ble_ll_conn.c         | 169 +++++++++++++------
 net/nimble/controller/src/ble_ll_conn_priv.h    |   8 +-
 net/nimble/drivers/nrf52/src/ble_phy.c          |   9 +-
 net/nimble/host/src/host_hci.c                  |   9 +-
 net/nimble/include/nimble/ble.h                 |   2 +-
 project/bletest/src/main.c                      |   8 +-
 8 files changed, 163 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/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 57705de..5fa2188 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -70,7 +70,6 @@ struct ble_ll_stats
     uint32_t hci_events_sent;
     uint32_t bad_ll_state;
     uint32_t bad_acl_hdr;
-    uint32_t bad_acl_datalen;
     uint32_t rx_bytes;
     uint32_t rx_valid_adv_pdus;
     uint32_t rx_invalid_adv_pdus;
@@ -95,7 +94,6 @@ struct ble_ll_stats
     uint32_t tx_l2cap_pdus;
     uint32_t tx_l2cap_bytes;
     uint32_t tx_empty_pdus;
-    uint32_t tx_empty_bytes;
 };
 extern struct ble_ll_stats g_ble_ll_stats;
 
@@ -329,13 +327,17 @@ uint8_t ble_ll_read_supp_features(void);
  * XXX: temporary LL debug log. Will get removed once we transition to real
  * log
  */ 
-#define BLE_LL_LOG
+#undef BLE_LL_LOG
 
 #define BLE_LL_LOG_ID_RX_START          (1)
 #define BLE_LL_LOG_ID_RX_END            (2)
-#define BLE_LL_LOG_ID_CONN_EV_START     (4)
-#define BLE_LL_LOG_ID_CONN_EV_END       (5)
-#define BLE_LL_LOG_ID_CONN_END          (6)
+#define BLE_LL_LOG_ID_CONN_EV_START     (10)
+#define BLE_LL_LOG_ID_CONN_TX           (15)
+#define BLE_LL_LOG_ID_CONN_RX           (16)
+#define BLE_LL_LOG_ID_CONN_TX_RETRY     (17)
+#define BLE_LL_LOG_ID_CONN_RX_ACK       (18)
+#define BLE_LL_LOG_ID_CONN_EV_END       (20)
+#define BLE_LL_LOG_ID_CONN_END          (30)
 #define BLE_LL_LOG_ID_PHY_SETCHAN       (200)
 #define BLE_LL_LOG_ID_PHY_DISABLE       (201)
 #define BLE_LL_LOG_ID_PHY_ISR           (202)
@@ -343,7 +345,7 @@ uint8_t ble_ll_read_supp_features(void);
 #define BLE_LL_LOG_ID_PHY_TX            (221)
 
 #ifdef BLE_LL_LOG
-void ble_ll_log(uint8_t id, uint8_t arg0_8, uint8_t arg1_8, uint32_t arg0_32);
+void ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32);
 #else
 #define ble_ll_log(m,n,o,p)
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/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 8ce85fc..f5f8357 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -82,20 +82,20 @@ os_stack_t g_ble_ll_stack[BLE_LL_STACK_SIZE];
 struct ble_ll_log
 {
     uint8_t log_id;
-    uint8_t log_arg8_0;
-    uint8_t log_arg8_1;
-    uint32_t log_arg32_0;
+    uint8_t log_a8;
+    uint16_t log_a16;
+    uint32_t log_a32;
     uint32_t cputime;
 
 };
 
-#define BLE_LL_LOG_LEN  (128)
+#define BLE_LL_LOG_LEN  (256)
 
 static struct ble_ll_log g_ble_ll_log[BLE_LL_LOG_LEN];
 static uint8_t g_ble_ll_log_index;
 
 void
-ble_ll_log(uint8_t id, uint8_t arg8_0, uint8_t arg8_1, uint32_t arg32_0)
+ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32)
 {
     os_sr_t sr;
     struct ble_ll_log *le;
@@ -104,9 +104,9 @@ ble_ll_log(uint8_t id, uint8_t arg8_0, uint8_t arg8_1, 
uint32_t arg32_0)
     le = &g_ble_ll_log[g_ble_ll_log_index];
     le->cputime = cputime_get32();
     le->log_id = id;
-    le->log_arg8_0 = arg8_0;
-    le->log_arg8_1 = arg8_1;
-    le->log_arg32_0 = arg32_0;
+    le->log_a8 = arg8;
+    le->log_a16 = arg16;
+    le->log_a32 = arg32;
     ++g_ble_ll_log_index;
     if (g_ble_ll_log_index == BLE_LL_LOG_LEN) {
         g_ble_ll_log_index = 0;
@@ -355,19 +355,6 @@ ble_ll_tx_pkt_in(void)
             continue;
         }
 
-        /* 
-         * XXX: fix this later: right now I need it all to be contiguous. If
-         * I cant make it contiguous, I will just free it here.
-         */
-        if (length > BLE_LL_CFG_ACL_DATA_PKT_LEN) {
-            /* Count these for noe */
-            ++g_ble_ll_stats.bad_acl_datalen;
-            os_mbuf_free(om);
-            continue;
-        }
-        om = os_mbuf_pullup(om, length);
-        assert(om);
-
         /* Hand to connection state machine */
         ble_ll_conn_tx_pkt_in(om, handle, length);
     }
@@ -577,13 +564,14 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, uint8_t chan, 
uint8_t crcok)
     uint16_t mblen;
     uint8_t *rxbuf;
 
-    ;
-    ble_ll_log(BLE_LL_LOG_ID_RX_END, chan, crcok, 
-               (BLE_MBUF_HDR_PTR(rxpdu))->end_cputime);
-
     /* Set the rx buffer pointer to the start of the received data */
     rxbuf = rxpdu->om_data;
 
+    ble_ll_log(BLE_LL_LOG_ID_RX_END, 
+               chan, 
+               ((uint16_t)crcok << 8) | rxbuf[1], 
+               (BLE_MBUF_HDR_PTR(rxpdu))->end_cputime);
+
     /* Check channel type */
     if (chan < BLE_PHY_NUM_DATA_CHANS) {
         /* Set length in the received PDU */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/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 96f3565..c09d70e 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -88,7 +88,7 @@ extern int ble_hs_rx_data(struct os_mbuf *om);
 /* LL configuration definitions */
 #define BLE_LL_CFG_SUPP_MAX_RX_BYTES        (251)
 #define BLE_LL_CFG_SUPP_MAX_TX_BYTES        (251)
-#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES   (27)
+#define BLE_LL_CFG_CONN_INIT_MAX_TX_BYTES   (251)
 
 /* Sleep clock accuracy table (in ppm) */
 static const uint16_t g_ble_sca_ppm_tbl[8] =
@@ -142,9 +142,13 @@ struct ble_ll_conn_stats
     uint32_t data_pdu_txg;
     uint32_t data_pdu_txf;
     uint32_t conn_req_txd;
+    uint32_t l2cap_enqueued;
 };
 struct ble_ll_conn_stats g_ble_ll_conn_stats;
 
+/* Some helpful macros */
+#define BLE_IS_RETRY_M(ble_hdr) ((ble_hdr)->txinfo.flags & BLE_MBUF_HDR_F_TXD)
+
 /**
  * Checks if pdu is a L2CAP pdu, meaning it is not a control pdu nor an empty 
  * pdu. Called only for transmit PDU's.
@@ -505,6 +509,8 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int 
beg_transition)
     uint8_t md;
     uint8_t hdr_byte;
     uint8_t end_transition;
+    uint8_t cur_txlen;
+    uint8_t rem_bytes;
     uint32_t ticks;
     struct os_mbuf *m;
     struct ble_mbuf_hdr *ble_hdr;
@@ -526,25 +532,68 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, 
int beg_transition)
     if (pkthdr) {
         m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
         nextpkthdr = STAILQ_NEXT(pkthdr, omp_next);
-        if (nextpkthdr && !connsm->terminate_ind_rxd) {
+        ble_hdr = BLE_MBUF_HDR_PTR(m);
+
+        /* 
+         * This piece of code is trying to determine if there are more bytes
+         * to send in the current packet AFTER the current fragment gets sent.
+         * If this is a retry we cant change the size and we use the 
+         * current tx size. If not, we use effective max transmit bytes for the
+         * connection.
+         */
+        if (BLE_IS_RETRY_M(ble_hdr)) {
+            cur_txlen = ble_hdr->txinfo.pyld_len;
+            hdr_byte = ble_hdr->txinfo.hdr_byte;
+            hdr_byte &= ~(BLE_LL_DATA_HDR_MD_MASK | BLE_LL_DATA_HDR_NESN_MASK);
+        } else {
+            /* Determine packet length we will transmit */
+            cur_txlen = connsm->eff_max_tx_octets;
+            rem_bytes = pkthdr->omp_len - ble_hdr->txinfo.offset;
+            if (cur_txlen > rem_bytes) {
+                cur_txlen = rem_bytes;
+            }
+
+            /* 
+             * Need to set LLID correctly if this is a fragment. Note
+             * that the LLID is already set the first time it is enqueued.
+             */ 
+            if (ble_hdr->txinfo.offset != 0) {
+                hdr_byte = BLE_LL_LLID_DATA_FRAG;
+            } else {
+                hdr_byte = ble_hdr->txinfo.hdr_byte;
+            }
+            if (connsm->tx_seqnum) {
+                hdr_byte |= BLE_LL_DATA_HDR_SN_MASK;
+            }
+            ble_hdr->txinfo.pyld_len = cur_txlen;
+        }
+
+        if ((nextpkthdr || 
+             ((ble_hdr->txinfo.offset + cur_txlen) < pkthdr->omp_len)) && 
+             !connsm->terminate_ind_rxd) {
             md = 1;
             if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
                 /* 
+                 * Dont bother to set the MD bit if we cannot do the following:
+                 *  -> wait IFS, send the current frame.
+                 *  -> wait IFS, receive a mininim size frame.
+                 *  -> wait IFS, send a mininim size frame.
+                 *  -> wait IFS, receive a mininim size frame.
+                 */
+                /* 
                  * XXX: this calculation is based on using the current time
                  * and assuming the transmission will occur an IFS time from
                  * now. This is not the most accurate especially if we have
                  * received a frame and we are replying to it.
                  */ 
-                ticks = (BLE_LL_IFS * 4) + (2 * connsm->eff_max_rx_time) +
-                    BLE_TX_DUR_USECS_M(pkthdr->omp_len) + 
-                    BLE_TX_DUR_USECS_M(nextpkthdr->omp_len);
+                ticks = (BLE_LL_IFS * 4) + (3 * BLE_LL_CONN_SUPP_TIME_MIN) +
+                    BLE_TX_DUR_USECS_M(cur_txlen);
                 ticks = cputime_usecs_to_ticks(ticks);
                 if ((cputime_get32() + ticks) >= connsm->ce_end_time) {
                     md = 0;
                 }
             }
         }
-        ble_hdr = BLE_MBUF_HDR_PTR(m);
     } else {
         /* 
          * Send empty pdu. Need to reset some items in the empty pdu since
@@ -553,9 +602,14 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int 
beg_transition)
         m = (struct os_mbuf *)&connsm->conn_empty_pdu;
         ble_hdr = BLE_MBUF_HDR_PTR(m);
         ble_hdr->txinfo.flags = 0;
-        ble_hdr->txinfo.hdr_byte = BLE_LL_LLID_DATA_FRAG;
         pkthdr = OS_MBUF_PKTHDR(m);
         STAILQ_INSERT_HEAD(&connsm->conn_txq, pkthdr, omp_next);
+
+        /* Set header of empty pdu */
+        hdr_byte = BLE_LL_LLID_DATA_FRAG;
+        if (connsm->tx_seqnum) {
+            hdr_byte |= BLE_LL_DATA_HDR_SN_MASK;
+        }
         tx_empty_pdu = 1;
     }
 
@@ -563,22 +617,8 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int 
beg_transition)
      * too close the end? We do this if we have a data packet but not
        if we send the empty pdu*/
 
-    /* Set SN, MD, NESN in transmit PDU */
-    hdr_byte = ble_hdr->txinfo.hdr_byte;
-
-    /* 
-     * If this is a retry, we keep the LLID and SN. If not, we presume
-     * that the LLID is set and all other bits are 0 in the first header
-     * byte.
-     */
-    if (ble_hdr->txinfo.flags & BLE_MBUF_HDR_F_TXD) {
-        hdr_byte &= ~(BLE_LL_DATA_HDR_MD_MASK | BLE_LL_DATA_HDR_NESN_MASK);
-    } else {
-        if (connsm->tx_seqnum) {
-            hdr_byte |= BLE_LL_DATA_HDR_SN_MASK;
-        }
-        ble_hdr->txinfo.flags |= BLE_MBUF_HDR_F_TXD;
-    }
+    /* Set transmitted flag */
+    ble_hdr->txinfo.flags |= BLE_MBUF_HDR_F_TXD;
 
     /* If we have more data, set the bit */
     if (md) {
@@ -615,9 +655,15 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int 
beg_transition)
 
     /* Set transmit end callback */
     ble_phy_set_txend_cb(txend_func, connsm);
-
     rc = ble_phy_tx(m, beg_transition, end_transition);
     if (!rc) {
+        /* Log transmit on connection state */
+        ble_ll_log(BLE_LL_LOG_ID_CONN_TX, 
+                   hdr_byte, 
+                   ((uint16_t)ble_hdr->txinfo.offset << 8) | 
+                              ble_hdr->txinfo.pyld_len,
+                   (uint32_t)m);
+
         /* Set flag denoting we transmitted a pdu */
         connsm->pdu_txd = 1;
 
@@ -627,15 +673,12 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, 
int beg_transition)
         /* Increment packets transmitted */
         if (tx_empty_pdu) {
             ++g_ble_ll_stats.tx_empty_pdus;
-            g_ble_ll_stats.tx_empty_bytes += BLE_LL_PDU_HDR_LEN;
         } else 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 + 
-                BLE_LL_PDU_HDR_LEN;
+            g_ble_ll_stats.tx_ctrl_bytes += ble_hdr->txinfo.pyld_len; 
         } else {
             ++g_ble_ll_stats.tx_l2cap_pdus;
-            g_ble_ll_stats.tx_l2cap_bytes += OS_MBUF_PKTHDR(m)->omp_len + 
-                BLE_LL_PDU_HDR_LEN;
+            g_ble_ll_stats.tx_l2cap_bytes += ble_hdr->txinfo.pyld_len;
         }
     }
 
@@ -993,22 +1036,22 @@ ble_ll_conn_datalen_update(struct ble_ll_conn_sm *connsm,
     send_event = 0;
 
     /* See if effective times have changed */
-    eff_time = min(connsm->rem_max_rx_time, connsm->max_rx_time);
+    eff_time = min(connsm->rem_max_tx_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);
+    eff_time = min(connsm->rem_max_rx_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);
+    eff_bytes = min(connsm->rem_max_tx_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);
+    eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_tx_octets);
     if (eff_bytes != connsm->eff_max_tx_octets) {
         connsm->eff_max_tx_octets = eff_bytes;
         send_event = 1;
@@ -1655,6 +1698,7 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa)
     uint8_t conn_sn;
     uint8_t conn_nesn;
     uint8_t reply;
+    uint8_t rem_bytes;
     uint32_t ticks;
     struct os_mbuf *txpdu;
     struct os_mbuf_pkthdr *pkthdr;
@@ -1711,6 +1755,9 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t aa)
         hdr_byte = rxpdu->om_data[0];
         connsm->last_rxd_hdr_byte = hdr_byte;
 
+        ble_ll_log(BLE_LL_LOG_ID_CONN_RX, hdr_byte, connsm->tx_seqnum,
+                   connsm->next_exp_seqnum);
+
         /* 
          * If SN bit from header does not match NESN in connection, this is
          * a resent PDU and should be ignored.
@@ -1739,30 +1786,39 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t 
aa)
                 connsm->tx_seqnum ^= 1;
                 ++g_ble_ll_conn_stats.data_pdu_txg;
 
-                /* We can remove this packet from the queue now */
+                /* 
+                 * Determine if we should remove packet from queue or if there
+                 * are more fragments to send.
+                 */
                 pkthdr = STAILQ_FIRST(&connsm->conn_txq);
                 if (pkthdr) {
-                    STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
                     txpdu = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
+                    txhdr = BLE_MBUF_HDR_PTR(txpdu);
 
                     /* Did we transmit a TERMINATE_IND? If so, we are done */
-                    txhdr = BLE_MBUF_HDR_PTR(txpdu);
                     if (ble_ll_ctrl_is_terminate_ind(txhdr->txinfo.hdr_byte, 
                                                      txpdu->om_data[0])) {
                         connsm->terminate_ind_txd = 1;
+                        STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
                         os_mbuf_free(txpdu);
                         rc = -1;
                         goto conn_rx_pdu_end;
-                    } else {
-                        /* 
-                         * If this is a l2cap pdu, we have to increment the
-                         * number of completed packets
-                         */
+                    }
+
+                    /* Increment offset based on number of bytes sent */
+                    txhdr->txinfo.offset += txhdr->txinfo.pyld_len;
+                    if (txhdr->txinfo.offset >= pkthdr->omp_len) {
+                        STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next);
+
+                        /* If l2cap pdu, increment # of completed packets */
                         if (ble_ll_conn_is_l2cap_pdu(txhdr)) {
                             ++connsm->completed_pkts;
                         }
+                        os_mbuf_free(txpdu);
+                    } else {
+                        /* More to go. Clear the TXD flag */
+                        txhdr->txinfo.flags &= ~BLE_MBUF_HDR_F_TXD;
                     }
-                    os_mbuf_free(txpdu);
                 } else {
                     /* No packet on queue? This is an error! */
                     ++g_ble_ll_conn_stats.no_tx_pdu;
@@ -1781,12 +1837,18 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint32_t 
aa)
             if (reply) {
                 pkthdr = STAILQ_FIRST(&connsm->conn_txq);
                 if (pkthdr) {
-                    ticks = BLE_TX_DUR_USECS_M(pkthdr->omp_len);
+                    txpdu = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
+                    txhdr = BLE_MBUF_HDR_PTR(txpdu);
+                    rem_bytes = pkthdr->omp_len - txhdr->txinfo.offset;
+                    if (rem_bytes > connsm->eff_max_tx_octets) {
+                        rem_bytes = connsm->eff_max_tx_octets;
+                    }
+                    ticks = BLE_TX_DUR_USECS_M(rem_bytes);
                 } else {
                     /* We will send empty pdu (just a LL header) */
                     ticks = BLE_TX_DUR_USECS_M(0);
                 }
-                ticks += (BLE_LL_IFS * 2) + connsm->eff_max_rx_time;
+                ticks += (BLE_LL_IFS * 2) + BLE_LL_CONN_SUPP_TIME_MIN;
                 ticks = cputime_usecs_to_ticks(ticks);
                 if ((rxhdr->end_cputime + ticks) >= connsm->ce_end_time) {
                     reply = 0;
@@ -1827,7 +1889,7 @@ conn_rx_pdu_end:
             BLE_TX_DUR_USECS_M(rxpdu->om_data[1]);
     }
 
-    /* If rc not 0, */
+    /* Send link layer a connection end event if over */
     if (rc) {
         ble_ll_event_send(&connsm->conn_ev_end);
     }
@@ -1851,10 +1913,20 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, 
struct os_mbuf *om,
 {
     os_sr_t sr;
     struct os_mbuf_pkthdr *pkthdr;
+    struct ble_mbuf_hdr *ble_hdr;
 
     /* Initialize the mbuf */
     ble_ll_mbuf_init(om, length, hdr_byte);
 
+    /* 
+     * We need to set the initial payload length if the total length of the
+     * PDU exceeds the maximum allowed for the connection for any single tx.
+     */
+    if (length > connsm->eff_max_tx_octets) {
+        ble_hdr = BLE_MBUF_HDR_PTR(om);
+        ble_hdr->txinfo.pyld_len = connsm->eff_max_tx_octets;
+    }
+
     /* Add to transmit queue for the connection */
     pkthdr = OS_MBUF_PKTHDR(om);
     OS_ENTER_CRITICAL(sr);
@@ -1886,14 +1958,15 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t 
handle, uint16_t length)
     connsm = ble_ll_conn_find_active_conn(conn_handle);
     if (connsm) {
         /* Construct LL header in buffer (NOTE: pb already checked) */
-        /* XXX: Currently length is less <= 251. Fix later */
-        assert(length <= 251);
         pb = handle & 0x3000;
         if (pb == 0) {
             hdr_byte = BLE_LL_LLID_DATA_START;
         } else {
             hdr_byte = BLE_LL_LLID_DATA_FRAG;
-        } 
+        }
+
+        /* Add to total l2cap pdus enqueue */
+        ++g_ble_ll_conn_stats.l2cap_enqueued;
 
         /* Clear flags field in BLE header */
         ble_ll_conn_enqueue_pkt(connsm, om, hdr_byte, length);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/net/nimble/controller/src/ble_ll_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h 
b/net/nimble/controller/src/ble_ll_conn_priv.h
index 3604550..48304b2 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -19,7 +19,13 @@
 
 #include "controller/ble_ll_conn.h"
 
-/* Definitions for max rx/tx time/bytes for connections */
+/* 
+ * Definitions for max rx/tx time/bytes for connections
+ *  NOTE: you get 327 usecs from 27 bytes of payload by:
+ *      -> adding 4 bytes for MIC
+ *      -> adding 2 bytes for PDU header
+ *      -> adding 8 bytes for preamble (1), access address (4) and crc (3).
+ */
 #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 */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/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 00762ea..7094ac6 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -164,7 +164,6 @@ ble_phy_isr(void)
     uint32_t irq_en;
     uint32_t state;
     uint32_t wfr_time;
-    uint32_t shortcuts;
     struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
@@ -182,13 +181,10 @@ ble_phy_isr(void)
         NRF_RADIO->EVENTS_DISABLED = 0;
         NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk;
         NRF_RADIO->EVENTS_END = 0;
-        shortcuts = NRF_RADIO->SHORTS;
+        state = NRF_RADIO->SHORTS;
 
         transition = g_ble_phy_data.phy_transition;
         if (transition == BLE_PHY_TRANSITION_TX_RX) {
-            /* Debug check to make sure we go from tx to rx */
-            assert((shortcuts & RADIO_SHORTS_DISABLED_RXEN_Msk) != 0);
-
             /* Clear the rx started flag */
             g_ble_phy_data.phy_rx_started = 0;
 
@@ -223,7 +219,6 @@ ble_phy_isr(void)
             wfr_time = NRF_TIMER0->CC[2];
             wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
             ble_ll_wfr_enable(wfr_time);
-
         } else {
             /* Better not be going from rx to tx! */
             assert(transition == BLE_PHY_TRANSITION_NONE);
@@ -326,7 +321,7 @@ ble_phy_isr(void)
 
 phy_isr_exit:
     /* Ensures IRQ is cleared */
-    shortcuts = NRF_RADIO->SHORTS;
+    state = NRF_RADIO->SHORTS;
 
     /* Count # of interrupts */
     ++g_ble_phy_stats.phy_isrs;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/net/nimble/host/src/host_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c
index 42110df..aff9504 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -595,14 +595,17 @@ host_hci_data_rx(struct os_mbuf *om)
     uint16_t handle;
     int rc;
 
-    console_printf("host_hci_data_rx(): ");
-    host_hci_log_pkt(om);
-
     rc = host_hci_data_hdr_strip(om, &hci_hdr);
     if (rc != 0) {
         goto done;
     }
 
+    console_printf("host_hci_data_rx(): handle=%u pb=%x len=%u data=",
+                   BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), 
+                   BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), 
+                   hci_hdr.hdh_len);
+    host_hci_log_pkt(om);
+
     if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) {
         rc = BLE_HS_EMSGSIZE;
         goto done;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/net/nimble/include/nimble/ble.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h
index 41587f8..170d6f4 100644
--- a/net/nimble/include/nimble/ble.h
+++ b/net/nimble/include/nimble/ble.h
@@ -68,7 +68,7 @@ struct ble_mbuf_hdr
     uint32_t end_cputime;
 };
 
-/* Flag definitions */
+/* Flag definitions. Apply to both txinfo and rxinfo */
 #define BLE_MBUF_HDR_F_DEVMATCH         (0x01)
 #define BLE_MBUF_HDR_F_CONN_REQ_TXD     (0x02)
 #define BLE_MBUF_HDR_F_TXD              (0x04)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/f95ce4fe/project/bletest/src/main.c
----------------------------------------------------------------------
diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c
index 6c4a71b..48555a3 100755
--- a/project/bletest/src/main.c
+++ b/project/bletest/src/main.c
@@ -92,6 +92,7 @@ struct os_callout_func g_bletest_timer;
 struct os_task bletest_task;
 os_stack_t bletest_stack[BLETEST_STACK_SIZE];
 uint32_t g_bletest_conn_end;
+#define BLETEST_PKT_SIZE                (128)
 
 void
 bletest_inc_adv_pkt_num(void)
@@ -343,10 +344,9 @@ bletest_execute(void)
             } else {
                 om = bletest_get_packet();
                 if (om) {
-
                     /* set payload length */
-                    pktlen = 32;
-                    om->om_len = 32 + 4;
+                    pktlen = BLETEST_PKT_SIZE;
+                    om->om_len = BLETEST_PKT_SIZE + 4;
 
                     /* Put the HCI header in the mbuf */
                     htole16(om->om_data, handle);
@@ -357,7 +357,7 @@ bletest_execute(void)
                     om->om_data[6] = 0;
                     om->om_data[7] = 0;
 
-                    /* Fill with incrementing pattern */
+                    /* Fill with incrementing pattern (starting from 1) */
                     for (i = 0; i < pktlen; ++i) {
                         om->om_data[8 + i] = (uint8_t)(i + 1);
                     }

Reply via email to