Repository: incubator-mynewt-larva Updated Branches: refs/heads/master 15a4a8cf3 -> 72c8e58aa
Merge new os mbuf changes into bletest 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/72c8e58a Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/72c8e58a Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/72c8e58a Branch: refs/heads/master Commit: 72c8e58aa8553807e5865df0dc87977f89e16acc Parents: 15a4a8c Author: wes3 <w...@micosa.io> Authored: Sun Nov 29 20:22:02 2015 -0800 Committer: wes3 <w...@micosa.io> Committed: Sun Nov 29 20:22:02 2015 -0800 ---------------------------------------------------------------------- libs/os/include/os/os_mbuf.h | 8 +-- net/nimble/controller/src/ble_ll.c | 4 +- net/nimble/controller/src/ble_ll_adv.c | 4 +- net/nimble/controller/src/ble_ll_conn.c | 78 +++++++++++++--------------- net/nimble/controller/src/ble_ll_scan.c | 2 +- net/nimble/drivers/native/src/ble_phy.c | 2 +- net/nimble/drivers/nrf52/src/ble_phy.c | 7 +-- net/nimble/include/nimble/ble.h | 15 ++++++ project/bletest/src/main.c | 5 +- 9 files changed, 66 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/libs/os/include/os/os_mbuf.h ---------------------------------------------------------------------- diff --git a/libs/os/include/os/os_mbuf.h b/libs/os/include/os/os_mbuf.h index dc16bf5..881ddba 100644 --- a/libs/os/include/os/os_mbuf.h +++ b/libs/os/include/os/os_mbuf.h @@ -20,9 +20,11 @@ #include "os/os_eventq.h" /** - * A mbuf pool to allocate a mbufs out of. This contains a pointer to the - * mempool to allocate mbufs out of, along with convenient housekeeping - * information on mbufs in the pool (e.g. length of variable packet header) + * A mbuf pool from which to allocate mbufs. This contains a pointer to the os + * mempool to allocate mbufs out of, the total number of elements in the pool, + * and the amount of "user" data in a non-packet header mbuf. The total pool + * size, in bytes, should be: + * os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf)) */ struct os_mbuf_pool { /** http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/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 c196725..679d859 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -349,7 +349,7 @@ ble_ll_rx_pkt_in_proc(void) } /* Free the packet buffer */ - os_mbuf_free(&g_mbuf_pool, m); + os_mbuf_free(m); } } } @@ -537,7 +537,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; - os_mbuf_free(&g_mbuf_pool, rxpdu); + os_mbuf_free(rxpdu); return -1; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/net/nimble/controller/src/ble_ll_adv.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_adv.c b/net/nimble/controller/src/ble_ll_adv.c index a04a395..334a918 100644 --- a/net/nimble/controller/src/ble_ll_adv.c +++ b/net/nimble/controller/src/ble_ll_adv.c @@ -1081,11 +1081,11 @@ ble_ll_adv_init(void) advsm->adv_txdone_ev.ev_arg = advsm; /* Get an advertising mbuf (packet header) and attach to state machine */ - advsm->adv_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool); + ble_get_packet(advsm->adv_pdu); assert(advsm->adv_pdu != NULL); /* Get a scan response mbuf (packet header) and attach to state machine */ - advsm->scan_rsp_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool); + ble_get_packet(advsm->scan_rsp_pdu); assert(advsm->scan_rsp_pdu != NULL); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/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 82700e1..053a743 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -52,13 +52,14 @@ * to be scheduled prior to the start of the event to account for the time it * takes to get a frame ready (which is pretty much the IFS time). * 14) Make sure we set LLID correctly! - * 15) So what if I fail an empty pdu? Do I have to specifically retransmit - * that one? If I were to take a new data pdu and replace the empty pdu with - * the new data pdu? Could I do this or is that bad? * 16) Make sure we are doing the right thing in the connection rx pdu start * and end functions if we are a slave. + * 17) Make sure BLE header flags (TXD bit) is cleared when put on txq of conn */ +/* XXX: this does not belong here! Move to transport? */ +extern int ble_hs_rx_data(struct os_mbuf *om); + /* * XXX: Possible improvements * 1) Not sure I like the fact that the wait for response timer will still @@ -135,6 +136,14 @@ struct ble_ll_conn_global_params struct ble_ll_conn_global_params g_ble_ll_conn_params; +/* + * 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 + * and we always want to have one available. The empty pdu length is of + * type uint32_t so we have 4 byte alignment. + */ +#define BLE_LL_EMPTY_PDU_MBUF_SIZE (((BLE_MBUF_PKT_OVERHEAD + 4) + 3) / 4) + /* Connection state machine */ struct ble_ll_conn_sm { @@ -218,6 +227,9 @@ struct ble_ll_conn_sm SLIST_ENTRY(ble_ll_conn_sm) conn_sle; STAILQ_ENTRY(ble_ll_conn_sm) conn_stqe; }; + + /* empty pdu for connection */ + uint32_t conn_empty_pdu[BLE_LL_EMPTY_PDU_MBUF_SIZE]; }; /* Pointer to connection state machine we are trying to create */ @@ -256,11 +268,6 @@ struct ble_ll_conn_stats }; struct ble_ll_conn_stats g_ble_ll_conn_stats; -/* "Dummy" mbuf containing an "Empty PDU" */ -#define BLE_LL_DUMMY_EMPTY_PDU_SIZE ((BLE_MBUF_PKT_OVERHEAD + 4) / 4) - -static uint32_t g_ble_ll_empty_pdu[BLE_LL_DUMMY_EMPTY_PDU_SIZE]; - /** * Get a connection state machine. */ @@ -583,9 +590,13 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int beg_transition) } } } + ble_hdr = BLE_MBUF_HDR_PTR(m); } else { /* Send empty pdu */ - m = (struct os_mbuf *)&g_ble_ll_empty_pdu; + m = (struct os_mbuf *)&connsm->conn_empty_pdu; + ble_hdr = BLE_MBUF_HDR_PTR(m); + ble_hdr->flags = 0; + m->om_data[0] = BLE_LL_LLID_DATA_FRAG; } /* Set SN, MD, NESN in transmit PDU */ @@ -596,7 +607,6 @@ ble_ll_conn_tx_data_pdu(struct ble_ll_conn_sm *connsm, int beg_transition) * that the LLID is set and all other bits are 0 in the first header * byte. */ - ble_hdr = BLE_MBUF_HDR_PTR(m); if (ble_hdr->flags & BLE_MBUF_HDR_F_TXD) { hdr_byte &= ~(BLE_LL_DATA_HDR_MD_MASK | BLE_LL_DATA_HDR_NESN_MASK); } else { @@ -1017,11 +1027,9 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) } STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next); - /* XXX: what happens if the empty PDU is on this list? Should - we check to make sure it is not? */ - m = (struct os_mbuf *)((uint8_t *)pkthdr - sizeof(struct os_mbuf)); - os_mbuf_free(&g_mbuf_pool, m); + os_mbuf_free(m); + /* XXX: emtpy pdu? */ } /* Make sure events off queue */ @@ -1712,6 +1720,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok) */ rxbuf = rxpdu->om_data; hdr_byte = rxbuf[0]; + acl_len = rxbuf[1]; if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) { connsm->allow_slave_latency = 1; @@ -1727,21 +1736,17 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok) /* Update last rxd sn */ connsm->last_rxd_sn = rxd_sn; - /* XXX: use the mbuf routine for this! */ + /* NOTE: there should be at least two bytes available */ + assert(OS_MBUF_LEADINGSPACE(rxpdu) >= 2); + os_mbuf_prepend(rxpdu, 2); + rxbuf = rxpdu->om_data; + /* Set ACL data packet header and send to host */ - acl_len = rxbuf[1]; acl_hdr = (hdr_byte & BLE_LL_DATA_HDR_LLID_MASK); acl_hdr = (acl_hdr << 12) | connsm->conn_handle; - rxpdu->om_data = rxpdu->om_data - 2; - rxbuf = rxpdu->om_data; htole16(rxbuf, acl_hdr); htole16(rxbuf + 2, acl_len); - - /* Add to length of mbuf and packet header */ - rxpdu->om_len += 2; - OS_MBUF_PKTHDR(rxpdu)->omp_len += 2; - - /* XXX: send to host */ + ble_hs_rx_data(rxpdu); return; } } else { @@ -1751,8 +1756,8 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, uint8_t crcok) ++g_ble_ll_conn_stats.data_pdu_rx_invalid; } - /* Free the packet buffer */ - os_mbuf_free(&g_mbuf_pool, rxpdu); + /* Free buffer */ + os_mbuf_free(rxpdu); } /** @@ -1853,8 +1858,8 @@ ble_ll_conn_rx_pdu_end(struct os_mbuf *rxpdu, uint8_t crcok) if (pkthdr) { STAILQ_REMOVE_HEAD(&connsm->conn_txq, omp_next); txpdu = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); - os_mbuf_free(&g_mbuf_pool, txpdu); - /* XXX: deal with empty pdu's. Cant free them */ + os_mbuf_free(txpdu); + /* XXX: emtpy pdu? */ } else { /* No packet on queue? This is an error! */ ++g_ble_ll_conn_stats.no_tx_pdu; @@ -2044,21 +2049,12 @@ ble_ll_conn_init(void) 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; - /* - * XXX: This approach may not work as I may need to keep these on the - * transmit packet queue of a connsm. If there are multiple state machines, - * I will need multiple empty PDU's. This is only true if I need to keep - * the empty PDU on the transmit queue for retransmission across connection - * events. - */ - /* Initialize dummy empty pdu */ - m = (struct os_mbuf *)&g_ble_ll_empty_pdu; - m->om_data = (uint8_t *)&g_ble_ll_empty_pdu[0]; - m->om_data += sizeof(struct os_mbuf) + sizeof(struct os_mbuf_pkthdr); + /* Initialize empty pdu */ + m = (struct os_mbuf *)&connsm->conn_empty_pdu; + m->om_data = (uint8_t *)&connsm->conn_empty_pdu[0]; + m->om_data += BLE_MBUF_PKT_OVERHEAD; m->om_len = 2; - m->om_flags = OS_MBUF_F_MASK(OS_MBUF_F_PKTHDR); OS_MBUF_PKTHDR(m)->omp_len = 2; m->om_data[0] = BLE_LL_LLID_DATA_FRAG; - m->om_data[1] = 0; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/net/nimble/controller/src/ble_ll_scan.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c index 6e97f26..9cfdd35 100644 --- a/net/nimble/controller/src/ble_ll_scan.c +++ b/net/nimble/controller/src/ble_ll_scan.c @@ -1165,7 +1165,7 @@ ble_ll_scan_init(void) scansm->scan_window = BLE_HCI_SCAN_WINDOW_DEF; /* Get a scan request mbuf (packet header) and attach to state machine */ - scansm->scan_req_pdu = os_mbuf_get_pkthdr(&g_mbuf_pool); + ble_get_packet(scansm->scan_req_pdu); assert(scansm->scan_req_pdu != NULL); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/net/nimble/drivers/native/src/ble_phy.c ---------------------------------------------------------------------- diff --git a/net/nimble/drivers/native/src/ble_phy.c b/net/nimble/drivers/native/src/ble_phy.c index dff2b1d..11e07a0 100644 --- a/net/nimble/drivers/native/src/ble_phy.c +++ b/net/nimble/drivers/native/src/ble_phy.c @@ -99,7 +99,7 @@ ble_phy_rxpdu_get(void) m = g_ble_phy_data.rxpdu; if (m == NULL) { - m = os_mbuf_get_pkthdr(&g_mbuf_pool); + ble_get_packet(m); if (!m) { ++g_ble_phy_stats.no_bufs; } else { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/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 37731dd..4d99869 100644 --- a/net/nimble/drivers/nrf52/src/ble_phy.c +++ b/net/nimble/drivers/nrf52/src/ble_phy.c @@ -96,15 +96,10 @@ ble_phy_rxpdu_get(void) m = g_ble_phy_data.rxpdu; if (m == NULL) { - m = os_mbuf_get_pkthdr(&g_mbuf_pool); + ble_get_packet(m); if (!m) { ++g_ble_phy_stats.no_bufs; } else { - /* - * XXX: fix this later but we need to prepend the ACL header - * which is 4 bytes but we re-use 2 bytes of the PDU header. - */ - m->om_data += 2; g_ble_phy_data.rxpdu = m; } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/net/nimble/include/nimble/ble.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h index 8d98f5a..08339e5 100644 --- a/net/nimble/include/nimble/ble.h +++ b/net/nimble/include/nimble/ble.h @@ -65,6 +65,21 @@ struct ble_mbuf_hdr sizeof(struct os_mbuf_pkthdr) + \ sizeof(struct ble_mbuf_hdr)) +/** + * Get a BLE packet. A packet is a BLE packet header mbuf with enough + * leading space for ACL data header (4 bytes). + * + * + * @return struct os_mbuf * + */ +static inline void +ble_get_packet(struct os_mbuf *om) +{ + om = os_mbuf_get_pkthdr(&g_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + if (om) { + om->om_data += 4; + } +} #define BLE_DEV_ADDR_LEN (6) extern uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/72c8e58a/project/bletest/src/main.c ---------------------------------------------------------------------- diff --git a/project/bletest/src/main.c b/project/bletest/src/main.c index 43186fb..26b314b 100755 --- a/project/bletest/src/main.c +++ b/project/bletest/src/main.c @@ -49,7 +49,7 @@ uint8_t g_host_adv_len; /* Create a mbuf pool of BLE mbufs */ #define MBUF_NUM_MBUFS (16) -#define MBUF_BUF_SIZE (256) +#define MBUF_BUF_SIZE (256 + sizeof(struct hci_data_hdr)) #define MBUF_MEMBLOCK_SIZE (MBUF_BUF_SIZE + BLE_MBUF_PKT_OVERHEAD) #define MBUF_MEMPOOL_SIZE OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE) @@ -367,8 +367,7 @@ main(void) rc = os_mempool_init(&g_mbuf_mempool, MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE, &g_mbuf_buffer[0], "mbuf_pool"); - rc = os_mbuf_pool_init(&g_mbuf_pool, &g_mbuf_mempool, - sizeof(struct ble_mbuf_hdr), MBUF_MEMBLOCK_SIZE, + rc = os_mbuf_pool_init(&g_mbuf_pool, &g_mbuf_mempool, MBUF_MEMBLOCK_SIZE, MBUF_NUM_MBUFS); assert(rc == 0);