You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/01/25 09:39:22 UTC

[GitHub] andrzej-kaczmarek closed pull request #755: nimble: mbuf optimization in controller

andrzej-kaczmarek closed pull request #755: nimble: mbuf optimization in controller
URL: https://github.com/apache/mynewt-core/pull/755
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/drivers/nimble/native/src/ble_phy.c b/hw/drivers/nimble/native/src/ble_phy.c
index 2333eb45c..1450585ba 100644
--- a/hw/drivers/nimble/native/src/ble_phy.c
+++ b/hw/drivers/nimble/native/src/ble_phy.c
@@ -67,6 +67,8 @@ struct ble_phy_statistics
 
 struct ble_phy_statistics g_ble_phy_stats;
 
+static uint8_t g_ble_phy_tx_buf[BLE_PHY_MAX_PDU_LEN];
+
 /* XCVR object to emulate transceiver */
 struct xcvr_data
 {
@@ -413,13 +415,11 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
 
 
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
+ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
 {
+    uint8_t hdr_byte;
     int rc;
 
-    /* Better have a pdu! */
-    assert(txpdu != NULL);
-
     if (ble_phy_state_get() != BLE_PHY_STATE_IDLE) {
         ble_phy_disable();
         ++g_ble_phy_stats.radio_state_errs;
@@ -439,8 +439,8 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     /* Set phy state to transmitting and count packet statistics */
     g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
     ++g_ble_phy_stats.tx_good;
-    g_ble_phy_stats.tx_bytes += OS_MBUF_PKTHDR(txpdu)->omp_len +
-        BLE_LL_PDU_HDR_LEN;
+    g_ble_phy_stats.tx_bytes += pducb(g_ble_phy_tx_buf, pducb_arg, &hdr_byte) +
+                                BLE_LL_PDU_HDR_LEN;
     rc = BLE_ERR_SUCCESS;
 
     return rc;
diff --git a/hw/drivers/nimble/nrf51/src/ble_phy.c b/hw/drivers/nimble/nrf51/src/ble_phy.c
index 175c652b5..b231fe73e 100644
--- a/hw/drivers/nimble/nrf51/src/ble_phy.c
+++ b/hw/drivers/nimble/nrf51/src/ble_phy.c
@@ -1084,17 +1084,15 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
 }
 
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
+ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
 {
     int rc;
     uint8_t *dptr;
     uint8_t payload_len;
+    uint8_t payload_off;
+    uint8_t hdr_byte;
     uint32_t state;
     uint32_t shortcuts;
-    struct ble_mbuf_hdr *ble_hdr;
-
-    /* Better have a pdu! */
-    assert(txpdu != NULL);
 
     /*
      * This check is to make sure that the radio is not in a state where
@@ -1102,9 +1100,6 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
      */
     nrf_wait_disabled();
 
-    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
-    payload_len = ble_hdr->txinfo.pyld_len;
-
     /*
      * XXX: Although we may not have to do this here, I clear all the PPI
      * that should not be used when transmitting. Some of them are only enabled
@@ -1119,10 +1114,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     if (g_ble_phy_data.phy_encrypted) {
         /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
         dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
-        dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = payload_len;
-        dptr[2] = 0;
-        dptr += 3;
+        payload_off = 3;
 
         NRF_CCM->SHORTS = 1;
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
@@ -1141,9 +1133,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 #endif
         /* RAM representation has S0 and LENGTH fields (2 bytes) */
         dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
-        dptr[0] = ble_hdr->txinfo.hdr_byte;
-        dptr[1] = payload_len;
-        dptr += 2;
+        payload_off = 2;
     }
 #else
 
@@ -1155,9 +1145,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 
     /* RAM representation has S0 and LENGTH fields (2 bytes) */
     dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
-    dptr[0] = ble_hdr->txinfo.hdr_byte;
-    dptr[1] = payload_len;
-    dptr += 2;
+    payload_off = 2;
 #endif
 
     NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_tx_buf[0];
@@ -1175,17 +1163,25 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     NRF_RADIO->SHORTS = shortcuts;
     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
 
-    /* Set transmitted payload length */
-    g_ble_phy_data.phy_tx_pyld_len = payload_len;
+    /* Set PDU payload */
+    payload_len = pducb(&dptr[payload_off], pducb_arg, &hdr_byte);
+
+    /* Set PDU header */
+    dptr[0] = hdr_byte;
+    dptr[1] = payload_len;
+    if (payload_off > 2) {
+        dptr[2] = 0;
+    }
 
     /* Set the PHY transition */
     g_ble_phy_data.phy_transition = end_trans;
 
+    /* Set transmitted payload length */
+    g_ble_phy_data.phy_tx_pyld_len = payload_len;
+
     /* If we already started transmitting, abort it! */
     state = NRF_RADIO->STATE;
     if (state != RADIO_STATE_STATE_Tx) {
-        /* Copy data from mbuf into transmit buffer */
-        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, payload_len, dptr);
 
         /* Set phy state to transmitting and count packet statistics */
         g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
diff --git a/hw/drivers/nimble/nrf52/src/ble_phy.c b/hw/drivers/nimble/nrf52/src/ble_phy.c
index 010b744dc..bb457a17a 100644
--- a/hw/drivers/nimble/nrf52/src/ble_phy.c
+++ b/hw/drivers/nimble/nrf52/src/ble_phy.c
@@ -1438,18 +1438,15 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs)
 }
 
 int
-ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
+ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans)
 {
     int rc;
     uint8_t *dptr;
     uint8_t *pktptr;
     uint8_t payload_len;
+    uint8_t hdr_byte;
     uint32_t state;
     uint32_t shortcuts;
-    struct ble_mbuf_hdr *ble_hdr;
-
-    /* Better have a pdu! */
-    assert(txpdu != NULL);
 
     /*
      * This check is to make sure that the radio is not in a state where
@@ -1457,9 +1454,6 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
      */
     nrf_wait_disabled();
 
-    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
-    payload_len = ble_hdr->txinfo.pyld_len;
-
     /*
      * XXX: Although we may not have to do this here, I clear all the PPI
      * that should not be used when transmitting. Some of them are only enabled
@@ -1497,11 +1491,6 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     pktptr = dptr;
 #endif
 
-    /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
-    dptr[0] = ble_hdr->txinfo.hdr_byte;
-    dptr[1] = payload_len;
-    dptr[2] = 0;
-    dptr += 3;
     NRF_RADIO->PACKETPTR = (uint32_t)pktptr;
 
     /* Clear the ready, end and disabled events */
@@ -1514,18 +1503,23 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     NRF_RADIO->SHORTS = shortcuts;
     NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
 
-    /* Set transmitted payload length */
-    g_ble_phy_data.phy_tx_pyld_len = payload_len;
+    /* Set PDU payload */
+    payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte);
+
+    /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
+    dptr[0] = hdr_byte;
+    dptr[1] = payload_len;
+    dptr[2] = 0;
 
     /* Set the PHY transition */
     g_ble_phy_data.phy_transition = end_trans;
 
+    /* Set transmitted payload length */
+    g_ble_phy_data.phy_tx_pyld_len = payload_len;
+
     /* If we already started transmitting, abort it! */
     state = NRF_RADIO->STATE;
     if (state != RADIO_STATE_STATE_Tx) {
-        /* Copy data from mbuf into transmit buffer */
-        os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, payload_len, dptr);
-
         /* Set phy state to transmitting and count packet statistics */
         g_ble_phy_data.phy_state = BLE_PHY_STATE_TX;
         STATS_INC(ble_phy_stats, tx_good);
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index 12b978653..3a028369a 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -437,6 +437,9 @@ int ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *hdr);
 /* Called by the PHY when a packet reception ends */
 int ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
 
+/* Helper callback to tx mbuf using ble_phy_tx() */
+uint8_t ble_ll_tx_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte);
+
 /*--- Controller API ---*/
 void ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr);
 
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index 3887a2a3e..c7d1d61fd 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -106,8 +106,11 @@ int ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs);
 /* Set the transmit end callback and argument */
 void ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg);
 
+typedef uint8_t (*ble_phy_tx_pducb_t)(uint8_t *dptr, void *pducb_arg,
+                                      uint8_t *hdr_byte);
+
 /* Place the PHY into transmit mode */
-int ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans);
+int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans);
 
 /* Place the PHY into receive mode */
 int ble_phy_rx(void);
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 3674a19b1..649a59cc8 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -1013,6 +1013,24 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
     return rc;
 }
 
+uint8_t
+ble_ll_tx_mbuf_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
+{
+    struct os_mbuf *txpdu;
+    struct ble_mbuf_hdr *ble_hdr;
+
+    txpdu = pducb_arg;
+    assert(txpdu);
+    ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
+
+    os_mbuf_copydata(txpdu, ble_hdr->txinfo.offset, ble_hdr->txinfo.pyld_len,
+                     dptr);
+
+    *hdr_byte = ble_hdr->txinfo.hdr_byte;
+
+    return ble_hdr->txinfo.pyld_len;
+}
+
 static void
 ble_ll_event_rx_pkt(struct os_event *ev)
 {
diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c
index 4c1bdeb89..3a62dc505 100644
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@ -71,7 +71,6 @@ struct ble_ll_adv_sm
 {
     uint8_t adv_enabled;
     uint8_t adv_instance;
-    uint8_t adv_len;
     uint8_t adv_chanmask;
     uint8_t adv_filter_policy;
     uint8_t own_addr_type;
@@ -94,7 +93,7 @@ struct ble_ll_adv_sm
     uint8_t adv_rpa[BLE_DEV_ADDR_LEN];
     uint8_t peer_addr[BLE_DEV_ADDR_LEN];
     uint8_t initiator_addr[BLE_DEV_ADDR_LEN];
-    uint8_t adv_data[BLE_ADV_DATA_MAX_LEN];
+    struct os_mbuf *adv_data;
     uint8_t scan_rsp_data[BLE_SCAN_RSP_DATA_MAX_LEN];
     uint8_t *conn_comp_ev;
     struct os_event adv_txdone_ev;
@@ -120,6 +119,9 @@ struct ble_ll_adv_sm
 #define BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD         0x08
 #define BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK  0x30 /* use helpers! */
 
+#define ADV_DATA_LEN(_advsm) \
+                ((_advsm->adv_data) ? OS_MBUF_PKTLEN(advsm->adv_data) : 0)
+
 static inline int
 ble_ll_adv_active_chanset_is_pri(struct ble_ll_adv_sm *advsm)
 {
@@ -274,16 +276,18 @@ ble_ll_adv_final_chan(struct ble_ll_adv_sm *advsm)
  *
  * @param advsm Pointer to advertisement state machine
  */
-static void
-ble_ll_adv_legacy_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
+static uint8_t
+ble_ll_adv_legacy_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
 {
+    struct ble_ll_adv_sm *advsm;
     uint8_t     adv_data_len;
-    uint8_t     *dptr;
     uint8_t     pdulen;
     uint8_t     pdu_type;
 
+    advsm = pducb_arg;
+
     /* assume this is not a direct ind */
-    adv_data_len = advsm->adv_len;
+    adv_data_len = ADV_DATA_LEN(advsm);
     pdulen = BLE_DEV_ADDR_LEN + adv_data_len;
 
     if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) {
@@ -322,11 +326,9 @@ ble_ll_adv_legacy_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
         pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND;
     }
 
-    /* Get the advertising PDU and initialize it*/
-    ble_ll_mbuf_init(m, pdulen, pdu_type);
+    *hdr_byte = pdu_type;
 
     /* Construct advertisement */
-    dptr = m->om_data;
     memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN);
     dptr += BLE_DEV_ADDR_LEN;
 
@@ -337,8 +339,10 @@ ble_ll_adv_legacy_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
 
     /* Copy in advertising data, if any */
     if (adv_data_len != 0) {
-        memcpy(dptr, advsm->adv_data, adv_data_len);
+        os_mbuf_copydata(advsm->adv_data, 0, adv_data_len, dptr);
     }
+
+    return pdulen;
 }
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
@@ -357,8 +361,8 @@ ble_ll_adv_secondary_pdu_payload_len(struct ble_ll_adv_sm *advsm)
           BLE_LL_EXT_ADV_DATA_INFO_SIZE;
 
     if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) &&
-            advsm->adv_len) {
-        len += advsm->adv_len;
+            ADV_DATA_LEN(advsm)) {
+        len += ADV_DATA_LEN(advsm);
     }
 
     if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR) {
@@ -393,10 +397,10 @@ ble_ll_adv_aux_scan_rsp_payload_len(struct ble_ll_adv_sm *advsm)
 /**
  * Create the advertising PDU
  */
-static void
-ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
+static uint8_t
+ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
 {
-    uint8_t *dptr;
+    struct ble_ll_adv_sm *advsm;
     uint8_t pdulen;
     uint8_t pdu_type;
 
@@ -411,8 +415,12 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
     uint8_t ext_hdr_flags;
     uint32_t offset;
 
+    advsm = pducb_arg;
+
+    assert(advsm->adv_data);
+
     if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
-        return ble_ll_adv_legacy_pdu_make(advsm, m);
+        return ble_ll_adv_legacy_pdu_make(dptr, advsm, hdr_byte);
     }
 
     pdulen = BLE_LL_EXT_ADV_HDR_LEN;
@@ -427,7 +435,7 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
         adva = true;
 
         if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) &&
-                advsm->adv_len) {
+                ADV_DATA_LEN(advsm)) {
             adv_data = true;
         }
 
@@ -487,7 +495,7 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
     /* TODO ACAD */
 
     if (adv_data) {
-        pdulen += advsm->adv_len;
+        pdulen += ADV_DATA_LEN(advsm);
     }
 
     /* Set TxAdd to random if needed. */
@@ -500,10 +508,7 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
     /* Set the PDU length in the state machine (includes header) */
     advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN;
 
-    ble_ll_mbuf_init(m, pdulen, pdu_type);
-
-    /* Construct advertisement */
-    dptr = m->om_data;
+    *hdr_byte = pdu_type;
 
     /* ext hdr len and adv mode */
     dptr[0] = ext_hdr_len | (adv_mode << 6);
@@ -556,27 +561,24 @@ ble_ll_adv_pdu_make(struct ble_ll_adv_sm *advsm, struct os_mbuf *m)
     }
 
     if (adv_data) {
-        memcpy(dptr, advsm->adv_data, advsm->adv_len);
-        dptr += advsm->adv_len;
+        os_mbuf_copydata(advsm->adv_data, 0, ADV_DATA_LEN(advsm), dptr);
+        dptr += ADV_DATA_LEN(advsm);
     }
+
+    return pdulen;
 }
 #endif
 
-static struct os_mbuf *
-ble_ll_adv_scan_rsp_legacy_pdu_make(struct ble_ll_adv_sm *advsm)
+static uint8_t
+ble_ll_adv_scan_rsp_legacy_pdu_make(uint8_t *dptr, void *pducb_arg,
+                                    uint8_t *hdr_byte)
 {
+    struct ble_ll_adv_sm *advsm;
     uint8_t     scan_rsp_len;
-    uint8_t     *dptr;
     uint8_t     pdulen;
     uint8_t     hdr;
-    struct os_mbuf *m;
 
-    /* Obtain scan response buffer */
-    m = os_msys_get_pkthdr(BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN + BLE_DEV_ADDR_LEN,
-                           sizeof(struct ble_mbuf_hdr));
-    if (!m) {
-        return NULL;
-    }
+    advsm = pducb_arg;
 
     /* Make sure that the length is valid */
     scan_rsp_len = advsm->scan_rsp_len;
@@ -589,7 +591,7 @@ ble_ll_adv_scan_rsp_legacy_pdu_make(struct ble_ll_adv_sm *advsm)
         hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
     }
 
-    ble_ll_mbuf_init(m, pdulen, hdr);
+    *hdr_byte = hdr;
 
     /*
      * The adva in this packet will be the same one that was being advertised
@@ -600,13 +602,12 @@ ble_ll_adv_scan_rsp_legacy_pdu_make(struct ble_ll_adv_sm *advsm)
      */
 
     /* Construct scan response */
-    dptr = m->om_data;
     memcpy(dptr, advsm->adva, BLE_DEV_ADDR_LEN);
     if (scan_rsp_len != 0) {
         memcpy(dptr + BLE_DEV_ADDR_LEN, advsm->scan_rsp_data, scan_rsp_len);
     }
 
-    return m;
+    return pdulen;
 }
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
@@ -615,18 +616,19 @@ ble_ll_adv_scan_rsp_legacy_pdu_make(struct ble_ll_adv_sm *advsm)
  *
  * @param advsm
  */
-static struct os_mbuf *
-ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm)
+static uint8_t
+ble_ll_adv_scan_rsp_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
 {
-    uint8_t     *dptr;
+    struct ble_ll_adv_sm *advsm;
     uint8_t     pdulen;
     uint8_t     ext_hdr_len;
     uint8_t     ext_hdr_flags;
     uint8_t     hdr;
-    struct os_mbuf *m;
+
+    advsm = pducb_arg;
 
     if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
-        return ble_ll_adv_scan_rsp_legacy_pdu_make(advsm);
+        return ble_ll_adv_scan_rsp_legacy_pdu_make(dptr, pducb_arg, hdr_byte);
     }
 
     ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE + BLE_LL_EXT_ADV_ADVA_SIZE;
@@ -638,22 +640,13 @@ ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm)
 
     pdulen = BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len + advsm->scan_rsp_len;
 
-    /* Obtain scan response buffer */
-    m = os_msys_get_pkthdr(pdulen, sizeof(struct ble_mbuf_hdr));
-    if (!m) {
-        return NULL;
-    }
-
     /* Set BLE transmit header */
     hdr = BLE_ADV_PDU_TYPE_AUX_SCAN_RSP;
     if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
         hdr |= BLE_ADV_PDU_HDR_TXADD_RAND;
     }
 
-    ble_ll_mbuf_init(m, pdulen, hdr);
-
-    /* Construct scan response */
-    dptr = m->om_data;
+    *hdr_byte = hdr;
 
     /* ext hdr len and adv mode (00b) */
     dptr[0] = ext_hdr_len;
@@ -681,24 +674,31 @@ ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm)
     memcpy(dptr, advsm->scan_rsp_data, advsm->scan_rsp_len);
     dptr += advsm->scan_rsp_len;
 
-    return m;
+    return pdulen;
 }
 
+struct aux_conn_rsp_data {
+    struct ble_ll_adv_sm *advsm;
+    uint8_t *peer;
+    uint8_t rxadd;
+};
+
 /**
  * Create a AUX connect response PDU
  *
  * @param advsm
  */
-static struct os_mbuf *
-ble_ll_adv_aux_conn_rsp_pdu_make(struct ble_ll_adv_sm *advsm, uint8_t *peer,
-                                 uint8_t rxadd)
+static uint8_t
+ble_ll_adv_aux_conn_rsp_pdu_make(uint8_t *dptr, void *pducb_arg,
+                                 uint8_t *hdr_byte)
 {
-    uint8_t     *dptr;
+    struct aux_conn_rsp_data *rsp_data;
     uint8_t     pdulen;
     uint8_t     ext_hdr_len;
     uint8_t     ext_hdr_flags;
     uint8_t     hdr;
-    struct os_mbuf *m;
+
+    rsp_data = pducb_arg;
 
     /* flags,AdvA and TargetA */
     ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE + BLE_LL_EXT_ADV_ADVA_SIZE +
@@ -708,22 +708,13 @@ ble_ll_adv_aux_conn_rsp_pdu_make(struct ble_ll_adv_sm *advsm, uint8_t *peer,
 
     pdulen = BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len;
 
-    /* Obtain scan response buffer */
-    m = os_msys_get_pkthdr(pdulen, sizeof(struct ble_mbuf_hdr));
-    if (!m) {
-        return NULL;
-    }
-
     /* Set BLE transmit header */
-    hdr = BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP | rxadd;
-    if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
+    hdr = BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP | rsp_data->rxadd;
+    if (rsp_data->advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) {
         hdr |= BLE_ADV_PDU_HDR_TXADD_MASK;
     }
 
-    ble_ll_mbuf_init(m, pdulen, hdr);
-
-    /* Construct connect response */
-    dptr = m->om_data;
+    *hdr_byte = hdr;
 
     /* ext hdr len and adv mode (00b) */
     dptr[0] = ext_hdr_len;
@@ -733,13 +724,13 @@ ble_ll_adv_aux_conn_rsp_pdu_make(struct ble_ll_adv_sm *advsm, uint8_t *peer,
     dptr[0] = ext_hdr_flags;
     dptr += 1;
 
-    memcpy(dptr, advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE);
+    memcpy(dptr, rsp_data->advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE);
     dptr += BLE_LL_EXT_ADV_ADVA_SIZE;
 
-    memcpy(dptr, peer, BLE_LL_EXT_ADV_TARGETA_SIZE);
+    memcpy(dptr, rsp_data->peer, BLE_LL_EXT_ADV_TARGETA_SIZE);
     dptr += BLE_LL_EXT_ADV_ADVA_SIZE;
 
-    return m;
+    return pdulen;
 }
 #endif
 
@@ -817,7 +808,6 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
     uint8_t end_trans;
     uint32_t txstart;
     struct ble_ll_adv_sm *advsm;
-    struct os_mbuf *adv_pdu;
 
     /* Get the state machine for the event */
     advsm = (struct ble_ll_adv_sm *)sch->cb_arg;
@@ -880,23 +870,12 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch)
         ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
     }
 
-    /* Get an advertising mbuf (packet header)  */
-    adv_pdu = os_msys_get_pkthdr(BLE_ADV_LEGACY_MAX_PKT_LEN,
-                                 sizeof(struct ble_mbuf_hdr));
-    if (!adv_pdu) {
-        ble_phy_disable();
-        goto adv_tx_done;
-    }
-
+    /* Transmit advertisement */
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-    ble_ll_adv_pdu_make(advsm, adv_pdu);
+    rc = ble_phy_tx(ble_ll_adv_pdu_make, advsm, end_trans);
 #else
-    ble_ll_adv_legacy_pdu_make(advsm, adv_pdu);
+    rc = ble_phy_tx(ble_ll_adv_legacy_pdu_make, advsm, end_trans);
 #endif
-
-    /* Transmit advertisement */
-    rc = ble_phy_tx(adv_pdu, end_trans);
-    os_mbuf_free_chain(adv_pdu);
     if (rc) {
         goto adv_tx_done;
     }
@@ -973,7 +952,6 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
     uint8_t end_trans;
     uint32_t txstart;
     struct ble_ll_adv_sm *advsm;
-    struct os_mbuf *adv_pdu;
 
     /* Get the state machine for the event */
     advsm = (struct ble_ll_adv_sm *)sch->cb_arg;
@@ -1027,19 +1005,8 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
         ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
     }
 
-    /* Get an advertising mbuf (packet header)  */
-    adv_pdu = os_msys_get_pkthdr(BLE_ADV_LEGACY_MAX_PKT_LEN,
-                                 sizeof(struct ble_mbuf_hdr));
-    if (!adv_pdu) {
-        ble_phy_disable();
-        goto adv_tx_done;
-    }
-
-    ble_ll_adv_pdu_make(advsm, adv_pdu);
-
     /* Transmit advertisement */
-    rc = ble_phy_tx(adv_pdu, end_trans);
-    os_mbuf_free_chain(adv_pdu);
+    rc = ble_phy_tx(ble_ll_adv_pdu_make, advsm, end_trans);
     if (rc) {
         goto adv_tx_done;
     }
@@ -1708,8 +1675,8 @@ int
 ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
 {
     uint8_t datalen;
-    uint8_t off = 0;
     struct ble_ll_adv_sm *advsm;
+    int ret;
 
     if (instance >= BLE_ADV_INSTANCES) {
         return BLE_ERR_INV_HCI_CMD_PARMS;
@@ -1744,7 +1711,7 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
             return BLE_ERR_INV_HCI_CMD_PARMS;
         }
 
-        if (!advsm->adv_enabled || !advsm->adv_len || datalen) {
+        if (!advsm->adv_enabled || !ADV_DATA_LEN(advsm) || datalen) {
             return BLE_ERR_INV_HCI_CMD_PARMS;
         }
 
@@ -1755,6 +1722,10 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
         /* TODO mark adv data as complete? */
         /* fall through */
     case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_INT:
+        if (!advsm->adv_data) {
+            return BLE_ERR_INV_HCI_CMD_PARMS;
+        }
+
         if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
             return BLE_ERR_INV_HCI_CMD_PARMS;
         }
@@ -1766,8 +1737,6 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
         if (advsm->adv_enabled) {
             return BLE_ERR_CMD_DISALLOWED;
         }
-
-        off = advsm->adv_len;
         break;
     case BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST:
         if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
@@ -1788,9 +1757,25 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
         return BLE_ERR_INV_HCI_CMD_PARMS;
     }
 
+    /* Need to allocate new mbuf if this is beginning of new data */
+    if (operation == BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE ||
+                        operation == BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_FIRST) {
+        if (advsm->adv_data) {
+            os_mbuf_free_chain(advsm->adv_data);
+        }
+
+        advsm->adv_data = os_msys_get_pkthdr(datalen, 0);
+        if (!advsm->adv_data) {
+            return BLE_ERR_MEM_CAPACITY;
+        }
+    }
+
+    assert(advsm->adv_data);
+
     /* Check for valid advertising data length */
-    if (datalen + off > BLE_ADV_DATA_MAX_LEN) {
-        advsm->adv_len = 0;
+    if (datalen + ADV_DATA_LEN(advsm) > BLE_ADV_DATA_MAX_LEN) {
+        os_mbuf_free_chain(advsm->adv_data);
+        advsm->adv_data = NULL;
         return BLE_ERR_MEM_CAPACITY;
     }
 
@@ -1800,8 +1785,12 @@ ble_ll_adv_set_adv_data(uint8_t *cmd, uint8_t instance, uint8_t operation)
 #endif
 
     /* Copy the new data into the advertising structure. */
-    advsm->adv_len = datalen + off;
-    memcpy(advsm->adv_data + off, cmd + 1, datalen);
+    ret = os_mbuf_append(advsm->adv_data, cmd + 1, datalen);
+    if (ret) {
+        os_mbuf_free_chain(advsm->adv_data);
+        advsm->adv_data = NULL;
+        return BLE_ERR_MEM_CAPACITY;
+    }
 
     return BLE_ERR_SUCCESS;
 }
@@ -1844,7 +1833,7 @@ ble_ll_adv_ext_set_param(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen)
     }
 
     if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) {
-        if (advsm->adv_len > BLE_ADV_LEGACY_DATA_MAX_LEN ||
+        if (ADV_DATA_LEN(advsm) > BLE_ADV_LEGACY_DATA_MAX_LEN ||
             advsm->scan_rsp_len > BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN) {
             return BLE_ERR_INV_HCI_CMD_PARMS;
         }
@@ -1880,7 +1869,7 @@ ble_ll_adv_ext_set_param(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen)
     }
 
     if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
-        if (advsm->adv_len || advsm->scan_rsp_len) {
+        if (ADV_DATA_LEN(advsm) || advsm->scan_rsp_len) {
             return BLE_ERR_INV_HCI_CMD_PARMS;
         }
 
@@ -2161,6 +2150,8 @@ ble_ll_adv_remove(uint8_t instance)
         return BLE_ERR_CMD_DISALLOWED;
     }
 
+    os_mbuf_free_chain(advsm->adv_data);
+
     ble_ll_adv_sm_init(advsm);
 
     return BLE_ERR_SUCCESS;
@@ -2213,7 +2204,9 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
     uint8_t *peer;
     struct ble_mbuf_hdr *ble_hdr;
     struct ble_ll_adv_sm *advsm;
-    struct os_mbuf *rsp;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    struct aux_conn_rsp_data rsp_data;
+#endif
 
     /* See if adva in the request (scan or connect) matches what we sent */
     advsm = g_ble_ll_cur_adv_sm;
@@ -2275,25 +2268,25 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
     rc = -1;
 
     if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_REQ) {
+        /* XXX TODO: assume we do not need to change phy mode */
+        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
+
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
         if (advsm->flags & BLE_LL_ADV_SM_FLAG_SCAN_REQ_NOTIF) {
             ble_ll_hci_ev_send_scan_req_recv(advsm->adv_instance, peer,
                                              peer_addr_type);
         }
 
-        rsp = ble_ll_adv_scan_rsp_pdu_make(advsm);
+        rc = ble_phy_tx(ble_ll_adv_scan_rsp_pdu_make, advsm,
+                        BLE_PHY_TRANSITION_NONE);
 #else
-        rsp = ble_ll_adv_scan_rsp_legacy_pdu_make(advsm);
+        rc = ble_phy_tx(ble_ll_adv_scan_rsp_legacy_pdu_make, advsm,
+                        BLE_PHY_TRANSITION_NONE);
 #endif
-        if (rsp) {
-            /* XXX TODO: assume we do not need to change phy mode */
-            ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
-            rc = ble_phy_tx(rsp, BLE_PHY_TRANSITION_NONE);
-            if (!rc) {
-                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_TXD;
-                STATS_INC(ble_ll_stats, scan_rsp_txg);
-            }
-            os_mbuf_free_chain(rsp);
+
+        if (!rc) {
+            ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_TXD;
+            STATS_INC(ble_ll_stats, scan_rsp_txg);
         }
     } else if (pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_REQ) {
         /*
@@ -2312,17 +2305,16 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
         }
 
         /* use remote address used over the air */
-        rsp = ble_ll_adv_aux_conn_rsp_pdu_make(advsm,
-                                               rxbuf + BLE_LL_PDU_HDR_LEN,
-                                               rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK);
-        if (rsp) {
-            ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
-            rc = ble_phy_tx(rsp, BLE_PHY_TRANSITION_NONE);
-            if (!rc) {
-                advsm->flags |= BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD;
-                STATS_INC(ble_ll_stats, aux_conn_rsp_tx);
-            }
-            os_mbuf_free_chain(rsp);
+        rsp_data.advsm = advsm;
+        rsp_data.peer = rxbuf + BLE_LL_PDU_HDR_LEN;
+        rsp_data.rxadd = rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK;
+
+        ble_phy_set_txend_cb(ble_ll_adv_tx_done, advsm);
+        rc = ble_phy_tx(ble_ll_adv_aux_conn_rsp_pdu_make, &rsp_data,
+                        BLE_PHY_TRANSITION_NONE);
+        if (!rc) {
+            advsm->flags |= BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD;
+            STATS_INC(ble_ll_stats, aux_conn_rsp_tx);
         }
 #endif
     }
diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c
index 040c657ac..03930660f 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -1383,7 +1383,7 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm)
 
     /* Set transmit end callback */
     ble_phy_set_txend_cb(txend_func, connsm);
-    rc = ble_phy_tx(m, end_transition);
+    rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, m, end_transition);
     if (!rc) {
         /* Log transmit on connection state */
         cur_txlen = ble_hdr->txinfo.pyld_len;
@@ -2865,7 +2865,7 @@ ble_ll_conn_request_send(uint8_t addr_type, uint8_t *adva, uint16_t txoffset,
     } else {
         ble_phy_set_txend_cb(ble_ll_conn_req_txend_init, NULL);
     }
-    rc = ble_phy_tx(m, end_trans);
+    rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, m, end_trans);
     return rc;
 }
 
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index adbd719be..f1935d2c1 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -2147,7 +2147,8 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
 #endif
             /* XXX: TODO assume we are on correct phy */
             ble_ll_scan_req_pdu_make(scansm, adv_addr, addr_type);
-            rc = ble_phy_tx(scansm->scan_req_pdu, BLE_PHY_TRANSITION_TX_RX);
+            rc = ble_phy_tx(ble_ll_tx_mbuf_pducb, scansm->scan_req_pdu,
+                            BLE_PHY_TRANSITION_TX_RX);
 
             if (rc == 0) {
                 /* Set "waiting for scan response" flag */


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services