MYNEWT-336: Allow for smaller mbufs in nimble. The controller should now support the usage of smaller mbufs. Please read the Jira ticket for more information regarding mbuf usage by the controller and nimble. The major change associated with this commit was fixing a routine that was called when data packets where enqueued to a connection. The code was assuming that all the data was in one mbuf and was overwriting the first mbuf in the chain with the total mbuf chain length (the packet header length). Also modified the bletest code to create chained mbufs if the total packet length being sent exceeded a single mbuf.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/ba2c6fc6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/ba2c6fc6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/ba2c6fc6 Branch: refs/heads/1_0_0_b1_dev Commit: ba2c6fc68073103bf04b75d59f4bb40941fb1f4c Parents: 2d92b6d Author: William San Filippo <[email protected]> Authored: Fri Nov 11 16:21:32 2016 -0800 Committer: Marko Kiiskila <[email protected]> Committed: Sun Nov 13 15:46:20 2016 -0800 ---------------------------------------------------------------------- apps/bletest/src/main.c | 107 +++++++++---------- .../controller/include/controller/ble_ll_adv.h | 1 + .../controller/include/controller/ble_ll_scan.h | 1 + net/nimble/controller/src/ble_ll.c | 5 + net/nimble/controller/src/ble_ll_adv.c | 5 +- net/nimble/controller/src/ble_ll_conn.c | 16 ++- net/nimble/controller/src/ble_ll_scan.c | 2 +- net/nimble/include/nimble/ble.h | 8 +- net/nimble/transport/uart/src/ble_hci_uart.c | 17 ++- 9 files changed, 80 insertions(+), 82 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/apps/bletest/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c index 45a8da2..dddfcce 100755 --- a/apps/bletest/src/main.c +++ b/apps/bletest/src/main.c @@ -623,18 +623,61 @@ bletest_get_packet(void) om = NULL; if (os_msys_num_free() >= 5) { - om = os_msys_get_pkthdr(BLE_MBUF_PAYLOAD_SIZE, - sizeof(struct ble_mbuf_hdr)); + om = os_msys_get_pkthdr(0, sizeof(struct ble_mbuf_hdr)); } return om; } +static struct os_mbuf * +bletest_send_packet(uint16_t handle) +{ + int j; + uint8_t val; + struct os_mbuf *om; + uint16_t pktlen; + + om = bletest_get_packet(); + if (om) { + /* set payload length */ +#if BLETEST_THROUGHPUT_TEST + pktlen = BLETEST_PKT_SIZE; +#else +#if (BLETEST_CFG_RAND_PKT_SIZE == 1) + pktlen = rand() % (BLETEST_MAX_PKT_SIZE + 1); +#else + pktlen = BLETEST_PKT_SIZE; +#endif +#endif + + /* Put the HCI header in the mbuf */ + htole16(om->om_data, handle); + htole16(om->om_data + 2, pktlen + 4); + + /* Place L2CAP header in packet */ + htole16(om->om_data + 4, pktlen); + om->om_data[6] = 0; + om->om_data[7] = 0; + om->om_len = 8; + OS_MBUF_PKTHDR(om)->omp_len = 8; + + /* Fill with incrementing pattern (starting from 1) */ + for (j = 0; j < pktlen; ++j) { + val = j + 1; + os_mbuf_append(om, &val, 1); + } + + /* Transmit it */ + ble_hci_trans_hs_acl_tx(om); + } + + return om; +} + static void bletest_execute_advertiser(void) { int i; #if (BLETEST_CONCURRENT_CONN_TEST == 1) - int j; #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) uint16_t mask; uint16_t reply_handle; @@ -642,7 +685,6 @@ bletest_execute_advertiser(void) #endif int rc; uint16_t handle; - uint16_t pktlen; struct os_mbuf *om; #if (BLETEST_THROUGHPUT_TEST == 1) os_sr_t sr; @@ -735,37 +777,8 @@ bletest_execute_advertiser(void) } handle = g_last_handle_used; if (ble_ll_conn_find_active_conn(handle)) { - om = bletest_get_packet(); + om = bletest_send_packet(handle); if (om) { - /* set payload length */ -#if (BLETEST_CFG_RAND_PKT_SIZE == 1) - pktlen = rand() % (BLETEST_MAX_PKT_SIZE + 1); -#else - pktlen = BLETEST_PKT_SIZE; - -#endif - /* Add header to length */ - om->om_len = pktlen + 4; - - /* Put the HCI header in the mbuf */ - htole16(om->om_data, handle); - htole16(om->om_data + 2, om->om_len); - - /* Place L2CAP header in packet */ - htole16(om->om_data + 4, pktlen); - om->om_data[6] = 0; - om->om_data[7] = 0; - om->om_len += 4; - - /* Fill with incrementing pattern (starting from 1) */ - for (j = 0; j < pktlen; ++j) { - om->om_data[8 + j] = (uint8_t)(j + 1); - } - - /* Add length */ - OS_MBUF_PKTHDR(om)->omp_len = om->om_len; - ble_hci_trans_hs_acl_tx(om); - /* Increment last handle used */ ++g_last_handle_used; } @@ -786,7 +799,6 @@ bletest_execute_advertiser(void) /* See if it is time to start throughput testing */ if ((int32_t)(os_time_get() - g_next_os_time) >= 0) { - /* Keep window full */ OS_ENTER_CRITICAL(sr); completed_pkts = g_bletest_completed_pkts; @@ -797,31 +809,8 @@ bletest_execute_advertiser(void) g_bletest_outstanding_pkts -= completed_pkts; while (g_bletest_outstanding_pkts < 20) { - om = bletest_get_packet(); + om = bletest_send_packet(g_bletest_handle); if (om) { - /* set payload length */ - pktlen = BLETEST_PKT_SIZE; - om->om_len = BLETEST_PKT_SIZE + 4; - - /* Put the HCI header in the mbuf */ - htole16(om->om_data, g_bletest_handle); - htole16(om->om_data + 2, om->om_len); - - /* Place L2CAP header in packet */ - htole16(om->om_data + 4, pktlen); - om->om_data[6] = 0; - om->om_data[7] = 0; - om->om_len += 4; - - /* Fill with incrementing pattern (starting from 1) */ - for (i = 0; i < pktlen; ++i) { - om->om_data[8 + i] = (uint8_t)(i + 1); - } - - /* Add length */ - OS_MBUF_PKTHDR(om)->omp_len = om->om_len; - ble_hci_trans_hs_acl_data_send(om); - ++g_bletest_outstanding_pkts; } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/net/nimble/controller/include/controller/ble_ll_adv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_adv.h b/net/nimble/controller/include/controller/ble_ll_adv.h index 613efc0..74eabdf 100644 --- a/net/nimble/controller/include/controller/ble_ll_adv.h +++ b/net/nimble/controller/include/controller/ble_ll_adv.h @@ -49,6 +49,7 @@ extern "C" { /* Maximum advertisement data length */ #define BLE_ADV_DATA_MAX_LEN (31) +#define BLE_ADV_MAX_PKT_LEN (37) /* * ADV_IND http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/net/nimble/controller/include/controller/ble_ll_scan.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h index f9689f0..9524b92 100644 --- a/net/nimble/controller/include/controller/ble_ll_scan.h +++ b/net/nimble/controller/include/controller/ble_ll_scan.h @@ -52,6 +52,7 @@ extern "C" { * scanning state. */ #define BLE_SCAN_RSP_DATA_MAX_LEN (31) +#define BLE_SCAN_MAX_PKT_LEN (37) /* Scanning state machine (used when initiating as well) */ struct ble_ll_scan_sm http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/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 3504b60..6aaaf5f 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -1092,6 +1092,11 @@ ble_ll_flush_pkt_queue(struct ble_ll_pkt_q *pktq) /** * Called to initialize a mbuf used by the controller * + * NOTE: this is only used when the mbuf is created by the controller; + * it should not be used for data packets (ACL data packets) that come from + * the host. This routine assumes that the entire pdu length can fit in + * one mbuf contiguously. + * * @param m * @param pdulen * @param hdr http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/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 a4c59c6..61a2291 100644 --- a/net/nimble/controller/src/ble_ll_adv.c +++ b/net/nimble/controller/src/ble_ll_adv.c @@ -302,7 +302,8 @@ ble_ll_adv_scan_rsp_pdu_make(struct ble_ll_adv_sm *advsm) struct os_mbuf *m; /* Obtain scan response buffer */ - m = os_msys_get_pkthdr(BLE_MBUF_PAYLOAD_SIZE, sizeof(struct ble_mbuf_hdr)); + m = os_msys_get_pkthdr(BLE_SCAN_RSP_DATA_MAX_LEN + BLE_DEV_ADDR_LEN, + sizeof(struct ble_mbuf_hdr)); if (!m) { return NULL; } @@ -418,7 +419,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) } /* Get an advertising mbuf (packet header) */ - adv_pdu = os_msys_get_pkthdr(BLE_MBUF_PAYLOAD_SIZE, + adv_pdu = os_msys_get_pkthdr(BLE_ADV_MAX_PKT_LEN, sizeof(struct ble_mbuf_hdr)); if (!adv_pdu) { ble_phy_disable(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/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 ec61fa4..e67408d 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -2903,15 +2903,24 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, struct ble_mbuf_hdr *ble_hdr; int lifo; - /* Initialize the mbuf */ - ble_ll_mbuf_init(om, length, hdr_byte); + /* Set mbuf length and packet length if a control PDU */ + if (hdr_byte == BLE_LL_LLID_CTRL) { + om->om_len = length; + OS_MBUF_PKTHDR(om)->omp_len = length; + } + + /* Set BLE transmit header */ + ble_hdr = BLE_MBUF_HDR_PTR(om); + ble_hdr->txinfo.flags = 0; + ble_hdr->txinfo.offset = 0; + ble_hdr->txinfo.pyld_len = length; + ble_hdr->txinfo.hdr_byte = 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; } @@ -2924,7 +2933,6 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, * If this is one of the following types we need to insert it at * head of queue. */ - ble_hdr = BLE_MBUF_HDR_PTR(om); llid = ble_hdr->txinfo.hdr_byte & BLE_LL_DATA_HDR_LLID_MASK; if (llid == BLE_LL_LLID_CTRL) { switch (om->om_data[0]) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/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 01b8b1b..c79b88e 100644 --- a/net/nimble/controller/src/ble_ll_scan.c +++ b/net/nimble/controller/src/ble_ll_scan.c @@ -1484,7 +1484,7 @@ ble_ll_scan_init(void) os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm); /* Get a scan request mbuf (packet header) and attach to state machine */ - scansm->scan_req_pdu = os_msys_get_pkthdr(BLE_MBUF_PAYLOAD_SIZE, + scansm->scan_req_pdu = os_msys_get_pkthdr(BLE_SCAN_MAX_PKT_LEN, sizeof(struct ble_mbuf_hdr)); assert(scansm->scan_req_pdu != NULL); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/net/nimble/include/nimble/ble.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h index 0c72c4d..bff3e9d 100644 --- a/net/nimble/include/nimble/ble.h +++ b/net/nimble/include/nimble/ble.h @@ -46,7 +46,7 @@ struct ble_encryption_block * struct os_mbuf (16) * struct os_mbuf_pkthdr (8) * struct ble_mbuf_hdr (8) - * Data buffer (BLE_MBUF_PAYLOAD_SIZE) + * Data buffer (payload size, in bytes) * * The BLE mbuf header contains the following: * flags: bitfield with the following values @@ -92,12 +92,6 @@ struct ble_mbuf_hdr uint32_t beg_cputime; }; -/* - * The payload size for BLE MBUFs. NOTE: this needs to accommodate a max size - * PHY pdu of 257 bytes. - */ -#define BLE_MBUF_PAYLOAD_SIZE (260) - #define BLE_MBUF_HDR_CRC_OK(hdr) \ ((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_CRC_OK) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ba2c6fc6/net/nimble/transport/uart/src/ble_hci_uart.c ---------------------------------------------------------------------- diff --git a/net/nimble/transport/uart/src/ble_hci_uart.c b/net/nimble/transport/uart/src/ble_hci_uart.c index 13b32d3..29d7f4d 100755 --- a/net/nimble/transport/uart/src/ble_hci_uart.c +++ b/net/nimble/transport/uart/src/ble_hci_uart.c @@ -961,23 +961,22 @@ ble_hci_trans_reset(void) int ble_hci_uart_init(void) { + int acl_data_length; int acl_block_size; int rc; ble_hci_uart_free_mem(); /* - * XXX: For now, we will keep the ACL buffer size such that it can - * accommodate BLE_MBUF_PAYLOAD_SIZE. It should be possible to make this - * user defined but more testing would need to be done in that case. The - * MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. - * - * XXX: Should the max acl data length be part of config? + * The MBUF payload size must accommodate the HCI data header size plus the + * maximum ACL data packet length. The ACL block size is the size of the + * mbufs we will allocate. */ - acl_block_size = BLE_MBUF_PAYLOAD_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD; + acl_data_length = MYNEWT_VAL(BLE_LL_ACL_PKT_SIZE); + ble_hci_uart_max_acl_datalen = acl_data_length; + acl_block_size = acl_data_length + BLE_MBUF_MEMBLOCK_OVERHEAD + + BLE_HCI_DATA_HDR_SZ; acl_block_size = OS_ALIGN(acl_block_size, OS_ALIGNMENT); - ble_hci_uart_max_acl_datalen = BLE_MBUF_PAYLOAD_SIZE - BLE_HCI_DATA_HDR_SZ; rc = mem_malloc_mempool(&ble_hci_uart_acl_pool, MYNEWT_VAL(BLE_HCI_ACL_BUF_COUNT), acl_block_size,
