You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/03/03 14:04:48 UTC

[mynewt-nimble] branch master updated (811d2a5 -> 045c3d1)

This is an automated email from the ASF dual-hosted git repository.

andk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git.


    from 811d2a5  babblesim: Add command line arg to specify bdaddr
     new 810ef5e  babblesim/edtt: Refactor queue handling
     new 52deeed  babblesim/edtt: Handle write bd addr
     new 3923f1b  babblesim/edtt: Fix le_data_read
     new 045c3d1  babblesim/edtt: Workaround EDTT not consuming cs/cc

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 babblesim/edtt/hci_transport/src/ble_hci_edtt.c    | 471 ++++++++-------------
 .../edtt/hci_transport/src/edtt_driver_bsim.c      |   5 +-
 babblesim/hw/bsp/nrf52_bsim/syscfg.yml             |   1 +
 3 files changed, 191 insertions(+), 286 deletions(-)

[mynewt-nimble] 02/04: babblesim/edtt: Handle write bd addr

Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 52deeedff1d66d2105d353997b43f603670e5ec9
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Feb 21 22:07:01 2022 +0100

    babblesim/edtt: Handle write bd addr
    
    Some test cases change public address during test so we need to handle
    this.
---
 babblesim/edtt/hci_transport/src/ble_hci_edtt.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
index b77f3c8..4c1662a 100644
--- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
+++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
@@ -12,6 +12,7 @@
 #include "sysinit/sysinit.h"
 #include "syscfg/syscfg.h"
 #include "os/os_eventq.h"
+#include "controller/ble_ll.h"
 
 /* BLE */
 #include "nimble/ble.h"
@@ -832,7 +833,7 @@ le_data_write(uint16_t size)
 }
 
 static void
-fake_set_public_address()
+fake_write_bd_addr_cc()
 {
     struct ble_hci_ev_command_complete *ev;
     struct ble_hci_ev *hci_ev;
@@ -858,6 +859,7 @@ edtt_poller(void *arg) {
     uint16_t command;
     uint16_t size;
     uint16_t opcode;
+    uint8_t bdaddr[6];
 
     /* Initialize HCI command opcode and response variables */
     waiting_opcode = 0;
@@ -917,8 +919,11 @@ edtt_poller(void *arg) {
                 edtt_read((uint8_t *) &opcode, sizeof(opcode), EDTTT_BLOCK);
 
                 if (opcode == BT_HCI_OP_VS_WRITE_BD_ADDR) {
-                    fake_set_public_address();
-                    read_excess_bytes(size - 2);
+                    edtt_read((uint8_t *) &bdaddr, sizeof(bdaddr), EDTTT_BLOCK);
+                    ble_ll_set_public_addr(bdaddr);
+                    fake_write_bd_addr_cc();
+                } else {
+                    assert(0);
                 }
                 break;
             default:

[mynewt-nimble] 01/04: babblesim/edtt: Refactor queue handling

Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 810ef5e9230a3641c5bfa9c886c91b4de38beec8
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Feb 21 20:45:07 2022 +0100

    babblesim/edtt: Refactor queue handling
    
    This reworks events handling in EDTT.
    
    The "service_events" routine is now handled in separate task which
    blocks until new event is put in queue. This is possible since we use
    os_eventq to pass events and this means any get from queue will put
    task to sleep properly and trigger context switch if necessary.
    
    The blocking edtt_read() will now sleep if not data is available instead
    of advancing time machine forward so it does not interfere with timing.
    OS_TICKS_PER_SEC was increased to 1024 to have better granularity and
    allow ~5ms sleep time for edtt poller task as required.
    
    Also some non-LL code is simplified to use simple calloc/free as it does
    not really seem to be cessary to use mempools there, i.e. we just need
    some memory block to pass data and it does not really matter how it's
    allocated. Also using calloc/free means we will never run out of memory
    so no need to check for that.
---
 babblesim/edtt/hci_transport/src/ble_hci_edtt.c    | 404 +++++++--------------
 .../edtt/hci_transport/src/edtt_driver_bsim.c      |   5 +-
 babblesim/hw/bsp/nrf52_bsim/syscfg.yml             |   1 +
 3 files changed, 138 insertions(+), 272 deletions(-)

diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
index 57cdc3b..b77f3c8 100644
--- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
+++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
@@ -11,8 +11,7 @@
 #include <bs_tracing.h>
 #include "sysinit/sysinit.h"
 #include "syscfg/syscfg.h"
-#include "os/os_cputime.h"
-#include "os/os.h"
+#include "os/os_eventq.h"
 
 /* BLE */
 #include "nimble/ble.h"
@@ -34,9 +33,6 @@
 #define BLE_HCI_EDTT_ACL         0x02
 #define BLE_HCI_EDTT_EVT         0x04
 
-#define K_NO_WAIT 0
-#define K_FOREVER 1
-
 #define BT_HCI_OP_VS_WRITE_BD_ADDR 0xFC06
 
 /* Callbacks for sending commands and acl data to ble_ll task */
@@ -84,33 +80,23 @@ static os_membuf_t ble_hci_edtt_acl_buf[
 
 /* A packet for queueing EDTT/HCI commands and events */
 struct ble_hci_edtt_pkt {
+    struct os_event ev;
     STAILQ_ENTRY(ble_hci_edtt_pkt) next;
     uint32_t timestamp;
     uint8_t type;
     void *data;
 };
 
-/* Memory pool for ble_hci_edtt_pkt packets */
-static struct os_mempool ble_hci_edtt_pkt_pool;
-static os_membuf_t ble_hci_edtt_pkt_buf[
-    OS_MEMPOOL_SIZE(BLE_HCI_EDTT_EVT_COUNT + 1 +
-                    MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT),
-                    sizeof(struct ble_hci_edtt_pkt))
-];
-
-STAILQ_HEAD(ble_hci_edtt_pkt_queue, ble_hci_edtt_pkt);
-static struct ble_hci_edtt_pkt_queue data_queue;
-static struct ble_hci_edtt_pkt_queue rx_queue;
-static struct ble_hci_edtt_pkt_queue event_queue;
+static struct os_eventq edtt_q_svc;
+static struct os_eventq edtt_q_data;
+static struct os_eventq edtt_q_event;
+static uint8_t edtt_q_event_count;
 
 static uint16_t waiting_opcode;
 static enum commands_t waiting_response;
-static uint8_t m_events;
 
-#define EDTT_POLLER_STACK_SZ OS_STACK_ALIGN(4000)
-static int edtt_poller_running;
 static struct os_task edtt_poller_task;
-static os_stack_t edtt_poller_stack[EDTT_POLLER_STACK_SZ];
+static struct os_task edtt_service_task;
 
 #if EDTT_HCI_LOGS
 extern unsigned int global_device_nbr;
@@ -184,7 +170,6 @@ static int
 ble_hci_edtt_acl_tx(struct os_mbuf *om)
 {
     struct ble_hci_edtt_pkt *pkt;
-    os_sr_t sr;
 
     /* If this packet is zero length, just free it */
     if (OS_MBUF_PKTLEN(om) == 0) {
@@ -192,18 +177,11 @@ ble_hci_edtt_acl_tx(struct os_mbuf *om)
         return 0;
     }
 
-    pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
-    if (pkt == NULL) {
-        os_mbuf_free_chain(om);
-        return BLE_ERR_MEM_CAPACITY;
-    }
-
+    pkt = calloc(1, sizeof(*pkt));
     pkt->type = BLE_HCI_EDTT_ACL;
     pkt->data = om;
 
-    OS_ENTER_CRITICAL(sr);
-    STAILQ_INSERT_TAIL(&rx_queue, pkt, next);
-    OS_EXIT_CRITICAL(sr);
+    os_eventq_put(&edtt_q_svc, &pkt->ev);
 
     return 0;
 }
@@ -212,20 +190,12 @@ static int
 ble_hci_edtt_cmdevt_tx(uint8_t *hci_ev, uint8_t edtt_type)
 {
     struct ble_hci_edtt_pkt *pkt;
-    os_sr_t sr;
-
-    pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
-    if (pkt == NULL) {
-        ble_hci_trans_buf_free(hci_ev);
-        return BLE_ERR_MEM_CAPACITY;
-    }
 
+    pkt = calloc(1, sizeof(*pkt));
     pkt->type = edtt_type;
     pkt->data = hci_ev;
 
-    OS_ENTER_CRITICAL(sr);
-    STAILQ_INSERT_TAIL(&rx_queue, pkt, next);
-    OS_EXIT_CRITICAL(sr);
+    os_eventq_put(&edtt_q_svc, &pkt->ev);
 
     return 0;
 }
@@ -242,58 +212,6 @@ ble_hci_edtt_set_rx_cbs(ble_hci_trans_rx_cmd_fn *cmd_cb,
     ble_hci_edtt_rx_acl_arg = acl_arg;
 }
 
-/* Free data buffer */
-static void
-ble_hci_edtt_free_buf(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl)
-{
-    switch (type) {
-        case BLE_HCI_EDTT_NONE:
-            break;
-
-        case BLE_HCI_EDTT_CMD:
-        case BLE_HCI_EDTT_EVT:
-            ble_hci_trans_buf_free(cmdevt);
-            break;
-
-        case BLE_HCI_EDTT_ACL:
-            os_mbuf_free_chain(acl);
-            break;
-
-        default:
-            assert(0);
-            break;
-    }
-}
-
-static void
-edtt_pkt_dequeue_and_free(struct ble_hci_edtt_pkt_queue *queue, struct ble_hci_edtt_pkt *pkt)
-{
-    /* Dequeue pkt header */
-    STAILQ_REMOVE(queue, pkt, ble_hci_edtt_pkt, next);
-    /* Free data buffer */
-    ble_hci_edtt_free_buf(pkt->type, pkt->data, pkt->data);
-    /* Free buffer of pkt header */
-    os_memblock_put(&ble_hci_edtt_pkt_pool, pkt);
-}
-
-/* Get first element of queue, without dequeueing */
-static struct ble_hci_edtt_pkt *
-edtt_pkt_get(struct ble_hci_edtt_pkt_queue *queue, uint8_t block)
-{
-    struct ble_hci_edtt_pkt *pkt;
-
-    if (block == K_FOREVER) {
-        while (STAILQ_EMPTY(queue)) {}
-
-        pkt = STAILQ_FIRST(queue);
-        assert(pkt != NULL);
-    } else {
-        pkt = STAILQ_FIRST(queue);
-    }
-
-    return pkt;
-}
-
 /**
  * Sends an HCI event from the controller to the host.
  *
@@ -435,35 +353,6 @@ ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb,
     ble_hci_edtt_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg);
 }
 
-void
-ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
-                     void *cmd_arg,
-                     ble_hci_trans_rx_acl_fn *acl_cb,
-                     void *acl_arg)
-{
-    ble_hci_edtt_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg);
-}
-
-int
-ble_hci_trans_reset(void)
-{
-    struct ble_hci_edtt_pkt *pkt;
-
-    while ((pkt = STAILQ_FIRST(&data_queue)) != NULL) {
-        edtt_pkt_dequeue_and_free(&data_queue, pkt);
-    }
-
-    while ((pkt = STAILQ_FIRST(&event_queue)) != NULL) {
-        edtt_pkt_dequeue_and_free(&event_queue, pkt);
-    }
-
-    while ((pkt = STAILQ_FIRST(&rx_queue)) != NULL) {
-        edtt_pkt_dequeue_and_free(&rx_queue, pkt);
-    }
-
-    return 0;
-}
-
 /**
  * @brief Clean out excess bytes from the input buffer
  */
@@ -556,23 +445,23 @@ echo(uint16_t size)
  * @brief Handle Command Complete HCI event
  */
 static void
-command_complete(struct ble_hci_ev *hdr)
+command_complete(struct ble_hci_ev *evt)
 {
-    struct ble_hci_ev_command_complete *evt = (void *) hdr->data;
+    struct ble_hci_ev_command_complete *evt_cc = (void *) evt->data;
     uint16_t response = waiting_response;
-    uint16_t size = hdr->length - sizeof(evt->num_packets) - sizeof(evt->opcode);
+    uint16_t size = evt->length - sizeof(evt_cc->num_packets) - sizeof(evt_cc->opcode);
 
-    if (evt->opcode == waiting_opcode) {
+    if (evt_cc->opcode == waiting_opcode) {
         bs_trace_raw_time(9, "Command complete for 0x%04x", waiting_opcode);
 
         edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK);
         edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
-        edtt_write((uint8_t *) &evt->status, sizeof(evt->status), EDTTT_BLOCK);
-        edtt_write((uint8_t *) &evt->return_params, size - sizeof(evt->status), EDTTT_BLOCK);
+        edtt_write((uint8_t *) &evt_cc->status, sizeof(evt_cc->status), EDTTT_BLOCK);
+        edtt_write((uint8_t *) &evt_cc->return_params, size - sizeof(evt_cc->status), EDTTT_BLOCK);
         waiting_opcode = 0;
     } else {
         bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status,"
-                             " expected 0x(%04x)", evt->opcode, waiting_opcode);
+                             " expected 0x(%04x)", evt_cc->opcode, waiting_opcode);
     }
 }
 
@@ -580,22 +469,22 @@ command_complete(struct ble_hci_ev *hdr)
  * @brief Handle Command Status HCI event
  */
 static void
-command_status(struct ble_hci_ev *buf)
+command_status(struct ble_hci_ev *evt)
 {
-    struct ble_hci_ev_command_status *evt = (void *) buf->data;
-    uint16_t opcode = evt->opcode;
+    struct ble_hci_ev_command_status *evt_cs = (void *) evt->data;
+    uint16_t opcode = evt_cs->opcode;
     uint16_t response = waiting_response;
     uint16_t size;
 
-    size = buf->length - sizeof(evt->num_packets) - sizeof(evt->opcode);
+    size = evt->length - sizeof(evt_cs->num_packets) - sizeof(evt_cs->opcode);
 
     if (opcode == waiting_opcode) {
         bs_trace_raw_time(9, "Command status for 0x%04x", waiting_opcode);
 
         edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK);
         edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
-        edtt_write((uint8_t *) &evt->status, sizeof(evt->status), EDTTT_BLOCK);
-        edtt_write((uint8_t *) &evt->num_packets, size - sizeof(evt->status), EDTTT_BLOCK);
+        edtt_write((uint8_t *) &evt_cs->status, sizeof(evt_cs->status), EDTTT_BLOCK);
+        edtt_write((uint8_t *) &evt_cs->num_packets, size - sizeof(evt_cs->status), EDTTT_BLOCK);
         waiting_opcode = 0;
     } else {
         bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status,"
@@ -603,105 +492,104 @@ command_status(struct ble_hci_ev *buf)
     }
 }
 
-/**
- * @brief Remove an event from the event queue
- */
 static void
-discard_event(void)
+free_data(struct ble_hci_edtt_pkt *pkt)
+{
+    assert(pkt);
+    os_mbuf_free_chain(pkt->data);
+    free(pkt);
+}
+
+static void
+free_event(struct ble_hci_edtt_pkt *pkt)
 {
-    struct ble_hci_edtt_pkt *evt = edtt_pkt_get(&event_queue, K_FOREVER);
-    edtt_pkt_dequeue_and_free(&event_queue, evt);
-    m_events--;
+    assert(pkt);
+    ble_hci_trans_buf_free((void *)pkt->data);
+    free(pkt);
 }
 
 /**
  * @brief Allocate and store an event in the event queue
  */
 static struct ble_hci_edtt_pkt *
-queue_event(struct ble_hci_ev *buf)
+queue_event(struct ble_hci_ev *evt)
 {
-    struct ble_hci_edtt_pkt *evt;
+    struct ble_hci_edtt_pkt *pkt;
 
-    evt = os_memblock_get(&ble_hci_edtt_pkt_pool);
-    if (evt) {
-        evt->timestamp = tm_get_hw_time();
-        evt->type = BLE_HCI_EDTT_EVT;
-        evt->data = buf;
+    pkt = calloc(1, sizeof(*pkt));
+    assert(pkt);
+    pkt->timestamp = tm_get_hw_time();
+    pkt->type = BLE_HCI_EDTT_EVT;
+    pkt->data = evt;
 
-        STAILQ_INSERT_TAIL(&event_queue, evt, next);
-        m_events++;
-    }
-    return evt;
+    os_eventq_put(&edtt_q_event, &pkt->ev);
+    edtt_q_event_count++;
+
+    return pkt;
+}
+
+static struct ble_hci_edtt_pkt *
+queue_data(struct os_mbuf *om)
+{
+    struct ble_hci_edtt_pkt *pkt;
+
+    pkt = calloc(1, sizeof(*pkt));
+    assert(pkt);
+    pkt->timestamp = tm_get_hw_time();
+    pkt->type = BLE_HCI_EDTT_ACL;
+    pkt->data = om;
+
+    os_eventq_put(&edtt_q_data, &pkt->ev);
+
+    return pkt;
 }
 
 /**
  * @brief Thread to service events and ACL data packets from the HCI input queue
  */
 static void
-service_events(void)
+service_events(void *arg)
 {
-    struct ble_hci_edtt_pkt *rx_pkt, *evt_pkt, *data_pkt;
-    struct ble_hci_ev *hdr;
-    struct os_mbuf *om;
+    struct ble_hci_edtt_pkt *pkt;
+    struct ble_hci_ev *evt;
 
-    rx_pkt = edtt_pkt_get(&rx_queue, K_NO_WAIT);
-    if (rx_pkt == NULL) {
-        return;
-    }
+    while (1) {
+        pkt = (void *)os_eventq_get(&edtt_q_svc);
 
-    if (rx_pkt->type == BLE_HCI_EDTT_EVT) {
-        hdr = (void *) rx_pkt->data;
+        if (pkt->type == BLE_HCI_EDTT_EVT) {
+            evt = (void *)pkt->data;
 
 #if EDTT_HCI_LOGS
-        log_hci_evt(hdr);
+            log_hci_evt(hdr);
 #endif
 
-        /* Prepare and send EDTT events */
-        switch (hdr->opcode) {
+            /* Prepare and send EDTT events */
+            switch (evt->opcode) {
             case BLE_HCI_EVCODE_COMMAND_COMPLETE:
-                evt_pkt = queue_event(hdr);
-                if (!evt_pkt) {
-                    discard_event();
-                    evt_pkt = queue_event(hdr);
-                }
-                command_complete(hdr);
+                queue_event(evt);
+                command_complete(evt);
                 break;
             case BLE_HCI_EVCODE_COMMAND_STATUS:
-                evt_pkt = queue_event(hdr);
-                if (!evt_pkt) {
-                    discard_event();
-                    evt_pkt = queue_event(hdr);
-                }
-                command_status(hdr);
+                queue_event(evt);
+                command_status(evt);
                 break;
             case BLE_HCI_EVCODE_NUM_COMP_PKTS:
                 /* EDTT does not handle this event and treats like fail */
             case BLE_HCI_OPCODE_NOP:
                 /* Ignore noop bytes from Link layer */
-                edtt_pkt_dequeue_and_free(&rx_queue, rx_pkt);
-                return;
+                ble_hci_trans_buf_free((void *)evt);
+                break;
             default:
                 /* Queue HCI events. We will send them to EDTT
                  * on CMD_GET_EVENT_REQ. */
-                evt_pkt = queue_event(hdr);
-                if (!evt_pkt) {
-                    bs_trace_raw_time(4, "Failed to allocated buffer for event!\n");
-                }
-        }
-    } else if (rx_pkt->type == BLE_HCI_EDTT_ACL) {
-        om = (struct os_mbuf *) rx_pkt->data;
-        data_pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
-
-        if (data_pkt) {
-            data_pkt->type = BLE_HCI_EDTT_ACL;
-            data_pkt->data = om;
-            STAILQ_INSERT_TAIL(&data_queue, data_pkt, next);
+                queue_event(evt);
+            }
+        } else if (pkt->type == BLE_HCI_EDTT_ACL) {
+            queue_data(pkt->data);
         }
-    }
 
-    /* Free only header buffer, not rx_pkt->data buffer */
-    STAILQ_REMOVE(&rx_queue, rx_pkt, ble_hci_edtt_pkt, next);
-    os_memblock_put(&ble_hci_edtt_pkt_pool, rx_pkt);
+        free(pkt);
+    }
 }
 
 /**
@@ -711,11 +599,11 @@ static void
 flush_events(uint16_t size)
 {
     uint16_t response = CMD_FLUSH_EVENTS_RSP;
-    struct ble_hci_edtt_pkt *buf;
+    struct ble_hci_edtt_pkt *pkt;
 
-    while ((buf = edtt_pkt_get(&event_queue, K_NO_WAIT))) {
-        edtt_pkt_dequeue_and_free(&event_queue, buf);
-        m_events--;
+    while ((pkt = (void *)os_eventq_get_no_wait(&edtt_q_event))) {
+        free_event(pkt);
+        edtt_q_event_count--;
     }
     read_excess_bytes(size);
     size = 0;
@@ -732,24 +620,24 @@ get_event(uint16_t size)
 {
     uint16_t response = CMD_GET_EVENT_RSP;
     struct ble_hci_edtt_pkt *pkt;
-    struct ble_hci_ev *hdr;
+    struct ble_hci_ev *evt;
 
     read_excess_bytes(size);
     size = 0;
 
     edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK);
-    pkt = edtt_pkt_get(&event_queue, K_FOREVER);
-
+    pkt = (void*)os_eventq_get(&edtt_q_event);
     if (pkt) {
-        hdr = pkt->data;
-        size = sizeof(pkt->timestamp) + sizeof(*hdr) + hdr->length;
+        evt = pkt->data;
+        size = sizeof(pkt->timestamp) + sizeof(*evt) + evt->length;
 
         edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
         edtt_write((uint8_t *)&pkt->timestamp, sizeof(pkt->timestamp), EDTTT_BLOCK);
-        edtt_write((uint8_t *)hdr, sizeof(*hdr) + hdr->length, EDTTT_BLOCK);
+        edtt_write((uint8_t *)evt, sizeof(*evt) + evt->length, EDTTT_BLOCK);
+
+        free_event(pkt);
 
-        edtt_pkt_dequeue_and_free(&event_queue, pkt);
-        m_events--;
+        edtt_q_event_count--;
     } else {
         edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
     }
@@ -763,8 +651,8 @@ get_events(uint16_t size)
 {
     uint16_t response = CMD_GET_EVENT_RSP;
     struct ble_hci_edtt_pkt *pkt;
-    struct ble_hci_ev *hdr;
-    uint8_t count = m_events;
+    struct ble_hci_ev *evt;
+    uint8_t count = edtt_q_event_count;
 
     read_excess_bytes(size);
     size = 0;
@@ -773,16 +661,18 @@ get_events(uint16_t size)
     edtt_write((uint8_t *)&count, sizeof(count), EDTTT_BLOCK);
 
     while (count--) {
-        pkt = edtt_pkt_get(&event_queue, K_FOREVER);
-        hdr = pkt->data;
-        size = sizeof(pkt->timestamp) + sizeof(*hdr) + hdr->length;
+        pkt = (void *)os_eventq_get_no_wait(&edtt_q_event);
+        assert(pkt);
+        evt = pkt->data;
+        size = sizeof(pkt->timestamp) + sizeof(*evt) + evt->length;
 
         edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
         edtt_write((uint8_t *)&pkt->timestamp, sizeof(pkt->timestamp), EDTTT_BLOCK);
-        edtt_write((uint8_t *)hdr, sizeof(*hdr) + hdr->length, EDTTT_BLOCK);
+        edtt_write((uint8_t *)evt, sizeof(*evt) + evt->length, EDTTT_BLOCK);
 
-        edtt_pkt_dequeue_and_free(&event_queue, pkt);
-        m_events--;
+        free_event(pkt);
+
+        edtt_q_event_count--;
     }
 }
 
@@ -800,7 +690,7 @@ has_event(uint16_t size)
     struct has_event_resp le_response = {
         .response = CMD_HAS_EVENT_RSP,
         .size = 1,
-        .count = m_events
+        .count = edtt_q_event_count
     };
 
     if (size > 0) {
@@ -816,11 +706,12 @@ static void
 le_flush_data(uint16_t size)
 {
     uint16_t response = CMD_LE_FLUSH_DATA_RSP;
-    struct ble_hci_edtt_pkt *buf;
+    struct ble_hci_edtt_pkt *pkt;
 
-    while ((buf = edtt_pkt_get(&data_queue, K_NO_WAIT))) {
-        edtt_pkt_dequeue_and_free(&data_queue, buf);
+    while ((pkt = (void *)os_eventq_get_no_wait(&edtt_q_data))) {
+        free_data(pkt);
     }
+
     read_excess_bytes(size);
     size = 0;
 
@@ -849,7 +740,8 @@ le_data_ready(uint16_t size)
         read_excess_bytes(size);
     }
 
-    if (STAILQ_EMPTY(&data_queue)) {
+    /* There's no API to check if eventq is empty but a little hack will do... */
+    if (edtt_q_data.evq_list.stqh_first == NULL) {
         le_response.empty = 1;
     }
 
@@ -870,8 +762,7 @@ le_data_read(uint16_t size)
     size = 0;
 
     edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK);
-    pkt = edtt_pkt_get(&data_queue, K_FOREVER);
-
+    pkt = (void *)os_eventq_get(&edtt_q_data);
     if (pkt) {
         om = pkt->data;
         size = OS_MBUF_PKTLEN(om);
@@ -882,8 +773,7 @@ le_data_read(uint16_t size)
             om = SLIST_NEXT(om, om_next);
         }
 
-        om = pkt->data;
-        os_mbuf_free_chain(om);
+        free_data(pkt);
     } else {
         edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
     }
@@ -968,13 +858,11 @@ edtt_poller(void *arg) {
     uint16_t command;
     uint16_t size;
     uint16_t opcode;
-    uint8_t received_cmd_bytes = 0;
-    os_sr_t sr;
 
     /* Initialize HCI command opcode and response variables */
     waiting_opcode = 0;
     waiting_response = CMD_NOTHING;
-    m_events = 0;
+    edtt_q_event_count = 0;
 
     /* Initialize and start EDTT system */
     enable_edtt_mode();
@@ -986,28 +874,12 @@ edtt_poller(void *arg) {
 #endif
 
     while (1) {
-        /* Try to receive a command without blocking */
-        received_cmd_bytes = edtt_read((uint8_t *) &command + received_cmd_bytes, sizeof(command) - received_cmd_bytes, EDTTT_NONBLOCK);
-
-        if (received_cmd_bytes < sizeof(command)) {
-            /* No command arrived - try to handle new ble_ll events */
-            service_events();
-
-            OS_ENTER_CRITICAL(sr);
-            /* Limited tick prevents bypassing EDTT timeouts,
-             * when a longer time gap between timers happens */
-            tm_tick_limited(6000);
-            OS_EXIT_CRITICAL(sr);
-            continue;
-        }
-
-        received_cmd_bytes = 0;
-
+        edtt_read((uint8_t *) &command, sizeof(command), EDTTT_BLOCK);
         edtt_read((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
 
         bs_trace_raw_time(4, "command 0x%04X received (size %u) "
                              "events=%u\n",
-                          command, size, m_events);
+                          command, size, edtt_q_event_count);
 
         switch (command) {
             case CMD_ECHO_REQ:
@@ -1061,15 +933,19 @@ edtt_poller(void *arg) {
 int
 edtt_init(void)
 {
+    os_stack_t dummy_stack;
     int rc;
 
-    if (!edtt_poller_running) {
-        edtt_poller_running = 1;
-        rc = os_task_init(&edtt_poller_task, "edttpoll", edtt_poller, NULL,
-                          MYNEWT_VAL(EDTT_POLLER_PRIO), OS_WAIT_FOREVER,
-                          edtt_poller_stack, EDTT_POLLER_STACK_SZ);
-        assert(rc == 0);
-    }
+    rc = os_task_init(&edtt_poller_task, "edttpoll", edtt_poller, NULL,
+                      MYNEWT_VAL(EDTT_POLLER_PRIO), OS_WAIT_FOREVER,
+                      &dummy_stack, 1);
+    assert(rc == 0);
+
+    rc = os_task_init(&edtt_service_task, "edttsvc", service_events, NULL,
+                      MYNEWT_VAL(EDTT_POLLER_PRIO) + 1, OS_WAIT_FOREVER,
+                      &dummy_stack, 1);
+    assert(rc == 0);
+
     return 0;
 }
 
@@ -1127,23 +1003,9 @@ ble_hci_edtt_init(void)
                          "ble_hci_edtt_evt_lo_pool");
     SYSINIT_PANIC_ASSERT(rc == 0);
 
-    /*
-     * Create memory pool of packet list nodes. NOTE: the number of these
-     * buffers should be, at least, the total number of event buffers (hi
-     * and lo), the number of command buffers (currently 1) and the total
-     * number of buffers that the controller could possibly hand to the host.
-     */
-    rc = os_mempool_init(&ble_hci_edtt_pkt_pool,
-                         BLE_HCI_EDTT_EVT_COUNT + 1 +
-                         MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT),
-                         sizeof (struct ble_hci_edtt_pkt),
-                         ble_hci_edtt_pkt_buf,
-                         "ble_hci_edtt_pkt_pool");
-    SYSINIT_PANIC_ASSERT(rc == 0);
-
     SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring edtt HCI");
 
-    STAILQ_INIT(&data_queue);
-    STAILQ_INIT(&event_queue);
-    STAILQ_INIT(&rx_queue);
+    os_eventq_init(&edtt_q_svc);
+    os_eventq_init(&edtt_q_event);
+    os_eventq_init(&edtt_q_data);
 }
diff --git a/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c b/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c
index 0e291ea..5fce526 100644
--- a/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c
+++ b/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c
@@ -18,6 +18,7 @@
 
 #include <time_machine.h>
 #include "edtt_driver.h"
+#include "os/os_sched.h"
 
 /* Recheck if something arrived from the EDTT every 5ms */
 #define EDTT_IF_RECHECK_DELTA 5 /* ms */
@@ -124,7 +125,9 @@ int edtt_read(uint8_t *ptr, size_t size, int flags)
 				bs_trace_raw_time(9, "EDTT: No enough data yet,"
 						"sleeping for %i ms\n",
 						EDTT_IF_RECHECK_DELTA);
-                tm_tick_limited(6000);
+                os_sched_sleep(os_sched_get_current_task(),
+                               os_time_ms_to_ticks32(EDTT_IF_RECHECK_DELTA));
+                os_sched(NULL);
 			} else {
 				bs_trace_raw_time(9, "EDTT: No enough data yet,"
 						"returning\n");
diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml
index b10d21d..5a45e9d 100644
--- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml
+++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml
@@ -35,6 +35,7 @@ syscfg.defs:
 
 syscfg.vals:
     HAL_SBRK: 0
+    OS_TICKS_PER_SEC: 1024
     OS_MAIN_STACK_SIZE: 8000
     MCU_TIMER_POLLER_PRIO: 0
     BLE_LL_PRIO: 1

[mynewt-nimble] 04/04: babblesim/edtt: Workaround EDTT not consuming cs/cc

Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 045c3d19cd5dfd4a6601ef814c41aea9dfdc0879
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Tue Feb 22 02:18:45 2022 +0100

    babblesim/edtt: Workaround EDTT not consuming cs/cc
    
    It seems that sometimes EDTT can send a command before cs/cc is consumed
    by get_event and this triggers an error since cmd buffer is reused for
    cs/cc and thus it will be queued as an event on edtt_q_event.
    
    Not sure if this is an EDTT issue/feature or smth on our side, for now
    we can workaround this by simply creating a copy of cs/cc which can be
    safely enqueued on edtt_q_event waiting to be consumed and freed by
    get_event while original cmd buffer is freed as soon as cs/cc is
    processed.
---
 babblesim/edtt/hci_transport/src/ble_hci_edtt.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
index d1ff77b..36db846 100644
--- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
+++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
@@ -330,10 +330,12 @@ ble_hci_trans_buf_free(uint8_t *buf)
     } else if (os_memblock_from(&ble_hci_edtt_evt_lo_pool, buf)) {
         rc = os_memblock_put(&ble_hci_edtt_evt_lo_pool, buf);
         assert(rc == 0);
-    } else {
+    } else if (os_memblock_from(&ble_hci_edtt_cmd_pool, buf)) {
         assert(os_memblock_from(&ble_hci_edtt_cmd_pool, buf));
         rc = os_memblock_put(&ble_hci_edtt_cmd_pool, buf);
         assert(rc == 0);
+    } else {
+        free(buf);
     }
 }
 
@@ -545,6 +547,19 @@ queue_data(struct os_mbuf *om)
     return pkt;
 }
 
+
+static void *
+dup_complete_evt(void *evt)
+{
+    struct ble_hci_ev *evt_copy;
+
+    evt_copy = calloc(1, BLE_HCI_TRANS_CMD_SZ);
+    memcpy(evt_copy, evt, BLE_HCI_TRANS_CMD_SZ);
+    ble_hci_trans_buf_free((void *)evt);
+
+    return evt_copy;
+}
+
 /**
  * @brief Thread to service events and ACL data packets from the HCI input queue
  */
@@ -568,10 +583,12 @@ service_events(void *arg)
             /* Prepare and send EDTT events */
             switch (evt->opcode) {
             case BLE_HCI_EVCODE_COMMAND_COMPLETE:
+                evt = dup_complete_evt(evt);
                 queue_event(evt);
                 command_complete(evt);
                 break;
             case BLE_HCI_EVCODE_COMMAND_STATUS:
+                evt = dup_complete_evt(evt);
                 queue_event(evt);
                 command_status(evt);
                 break;

[mynewt-nimble] 03/04: babblesim/edtt: Fix le_data_read

Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 3923f1bb1e9a29c6d71819fa5e228669629943cf
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Tue Feb 22 01:10:19 2022 +0100

    babblesim/edtt: Fix le_data_read
---
 babblesim/edtt/hci_transport/src/ble_hci_edtt.c | 37 ++++++++++++++++++-------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
index 4c1662a..d1ff77b 100644
--- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
+++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c
@@ -553,6 +553,7 @@ service_events(void *arg)
 {
     struct ble_hci_edtt_pkt *pkt;
     struct ble_hci_ev *evt;
+    struct ble_hci_ev_num_comp_pkts *evt_ncp;
 
     while (1) {
         pkt = (void *)os_eventq_get(&edtt_q_svc);
@@ -575,7 +576,16 @@ service_events(void *arg)
                 command_status(evt);
                 break;
             case BLE_HCI_EVCODE_NUM_COMP_PKTS:
-                /* EDTT does not handle this event and treats like fail */
+                evt_ncp = (void *)evt->data;
+                /* This should always be true for NimBLE LL */
+                assert(evt_ncp->count == 1);
+                if (evt_ncp->completed[0].packets == 0) {
+                    /* Discard, because EDTT does not like it */
+                    ble_hci_trans_buf_free((void *)evt);
+                } else {
+                    queue_event(evt);
+                }
+                break;
             case BLE_HCI_OPCODE_NOP:
                 /* Ignore noop bytes from Link layer */
                 ble_hci_trans_buf_free((void *)evt);
@@ -766,8 +776,11 @@ le_data_read(uint16_t size)
     pkt = (void *)os_eventq_get(&edtt_q_data);
     if (pkt) {
         om = pkt->data;
-        size = OS_MBUF_PKTLEN(om);
+
+        size = sizeof(pkt->timestamp) + OS_MBUF_PKTLEN(om);
+
         edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
+        edtt_write((uint8_t *)&pkt->timestamp, sizeof(pkt->timestamp), EDTTT_BLOCK);
 
         while (om != NULL) {
             edtt_write((uint8_t *)om->om_data, om->om_len, EDTTT_BLOCK);
@@ -801,17 +814,21 @@ le_data_write(uint16_t size)
     int err;
 
     if (size >= sizeof(hdr)) {
-        edtt_read((uint8_t *) &hdr, sizeof(hdr), EDTTT_BLOCK);
-        size -= sizeof(hdr);
         om = ble_hci_trans_acl_buf_alloc();
-
         if (om) {
-            memcpy(OS_MBUF_USRHDR(om), &hdr, sizeof(hdr));
-            uint16_t hdr_length = hdr.hdh_len;
+            edtt_read((void *)&hdr, sizeof(hdr), EDTTT_BLOCK);
+            size -= sizeof(hdr);
+
+            os_mbuf_append(om, &hdr, sizeof(hdr));
+
+            if (size >= hdr.hdh_len) {
+                /* Don't care, we have plenty of stack */
+                uint8_t tmp[hdr.hdh_len];
+
+                edtt_read(tmp, hdr.hdh_len, EDTTT_BLOCK);
+                size -= hdr.hdh_len;
 
-            if (size >= hdr_length) {
-                edtt_read(om->om_data, hdr_length, EDTTT_BLOCK);
-                size -= hdr_length;
+                os_mbuf_append(om, tmp, hdr.hdh_len);
             }
 
             err = ble_hci_edtt_rx_acl_cb(om, NULL);