BLE Host - Use HCI transport API Prior to this change, the host assumed it was running with a combined host-controller setup. Now it uses the available HCI transport instead.
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/2444d8f6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/2444d8f6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/2444d8f6 Branch: refs/heads/develop Commit: 2444d8f66060385b3b3dce29b1b7ff09cacdf9eb Parents: c970865 Author: Christopher Collins <[email protected]> Authored: Wed Aug 3 19:44:39 2016 -0700 Committer: Christopher Collins <[email protected]> Committed: Wed Aug 3 19:54:16 2016 -0700 ---------------------------------------------------------------------- .../controller/include/controller/ble_ll.h | 1 + net/nimble/controller/pkg.yml | 6 +- net/nimble/controller/src/ble_ll.c | 17 + net/nimble/controller/src/ble_ll_conn.c | 6 +- net/nimble/controller/src/ble_ll_conn_hci.c | 9 +- net/nimble/controller/src/ble_ll_conn_priv.h | 7 + net/nimble/controller/src/ble_ll_hci.c | 14 +- net/nimble/controller/src/ble_ll_hci_ev.c | 15 +- net/nimble/controller/src/ble_ll_scan.c | 3 +- net/nimble/host/include/host/ble_hs.h | 28 +- net/nimble/host/include/host/ble_hs_test.h | 3 - net/nimble/host/include/host/host_hci.h | 8 +- net/nimble/host/pkg.yml | 15 +- net/nimble/host/src/ble_gap.c | 2 +- net/nimble/host/src/ble_gap_priv.h | 2 +- net/nimble/host/src/ble_hci_cmd.c | 58 +- net/nimble/host/src/ble_hs.c | 224 ++++-- net/nimble/host/src/ble_hs_atomic.c | 20 + net/nimble/host/src/ble_hs_atomic_priv.h | 1 + net/nimble/host/src/ble_hs_priv.h | 16 + net/nimble/host/src/ble_hs_pvcy.c | 27 +- net/nimble/host/src/ble_hs_pvcy_priv.h | 2 +- net/nimble/host/src/ble_hs_startup.c | 4 - net/nimble/host/src/host_dbg.c | 2 +- net/nimble/host/src/host_hci.c | 49 +- net/nimble/host/src/host_hci_cmd.c | 52 +- net/nimble/host/src/test/ble_gap_test.c | 11 +- net/nimble/host/src/test/ble_host_hci_test.c | 8 +- net/nimble/host/src/test/ble_hs_test.c | 16 - net/nimble/host/src/test/ble_hs_test_util.c | 96 ++- net/nimble/host/src/test/ble_hs_test_util.h | 2 + net/nimble/host/src/test/ble_os_test.c | 2 +- net/nimble/host/src/test/ble_sm_test_util.c | 20 +- net/nimble/include/nimble/ble.h | 4 - net/nimble/include/nimble/ble_hci_trans.h | 152 ++++ net/nimble/include/nimble/hci_transport.h | 32 - .../ram/include/transport/ram/ble_hci_ram.h | 15 + net/nimble/transport/ram/pkg.yml | 33 + net/nimble/transport/ram/src/ble_hci_ram.c | 190 +++++ .../uart/include/transport/uart/ble_hci_uart.h | 19 + net/nimble/transport/uart/pkg.yml | 34 + net/nimble/transport/uart/src/ble_hci_uart.c | 775 +++++++++++++++++++ 42 files changed, 1731 insertions(+), 269 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/include/controller/ble_ll.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h index 81cba53..2be8425 100644 --- a/net/nimble/controller/include/controller/ble_ll.h +++ b/net/nimble/controller/include/controller/ble_ll.h @@ -22,6 +22,7 @@ #include "stats/stats.h" #include "hal/hal_cputime.h" +#include "os/os_eventq.h" #include "nimble/nimble_opt.h" /* Controller revision. */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/pkg.yml ---------------------------------------------------------------------- diff --git a/net/nimble/controller/pkg.yml b/net/nimble/controller/pkg.yml index 07a9d56..8e52aba 100644 --- a/net/nimble/controller/pkg.yml +++ b/net/nimble/controller/pkg.yml @@ -25,10 +25,14 @@ pkg.keywords: - ble - bluetooth -pkg.req_apis: ble_driver +pkg.req_apis: + - ble_driver + - ble_transport + pkg.deps: - libs/os - sys/stats - net/nimble + pkg.features: - BLE_DEVICE http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/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 3a09e3e..1a4f558 100644 --- a/net/nimble/controller/src/ble_ll.c +++ b/net/nimble/controller/src/ble_ll.c @@ -26,6 +26,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "controller/ble_hw.h" #include "controller/ble_phy.h" #include "controller/ble_ll.h" @@ -182,6 +183,9 @@ STATS_NAME_END(ble_ll_stats) struct os_task g_ble_ll_task; os_stack_t g_ble_ll_stack[BLE_LL_STACK_SIZE]; +struct os_mempool g_ble_ll_hci_ev_pool; +static void *ble_ll_hci_os_event_buf; + /* XXX: temporary logging until we transition to real logging */ #ifdef BLE_LL_LOG struct ble_ll_log @@ -1129,6 +1133,16 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size) cputime_timer_init(&g_ble_ll_data.ll_wfr_timer, ble_ll_wfr_timer_exp, NULL); + ble_ll_hci_os_event_buf = malloc( + OS_MEMPOOL_BYTES(16, sizeof (struct os_event))); + assert(ble_ll_hci_os_event_buf != NULL); + + /* Create memory pool of OS events */ + rc = os_mempool_init(&g_ble_ll_hci_ev_pool, 16, + sizeof (struct os_event), ble_ll_hci_os_event_buf, + "g_ble_ll_hci_ev_pool"); + assert(rc == 0); + /* Initialize LL HCI */ ble_ll_hci_init(); @@ -1182,6 +1196,9 @@ ble_ll_init(uint8_t ll_task_prio, uint8_t num_acl_pkts, uint16_t acl_pkt_size) STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32), STATS_NAME_INIT_PARMS(ble_ll_stats), "ble_ll"); + + ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, + ble_ll_hci_acl_rx, NULL); return rc; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/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 f711dfb..cb0f89b 100644 --- a/net/nimble/controller/src/ble_ll_conn.c +++ b/net/nimble/controller/src/ble_ll_conn.c @@ -25,6 +25,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "ble/xcvr.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" @@ -103,9 +104,6 @@ extern void bletest_completed_pkt(uint16_t handle); * are hosed. Well, anchor point can get really messed up! */ -/* XXX: this does not belong here! Move to transport? */ -extern int ble_hs_rx_data(struct os_mbuf *om); - /* * The amount of time that we will wait to hear the start of a receive * packet after we have transmitted a packet. This time is at least @@ -2569,7 +2567,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) acl_hdr = (acl_hdr << 12) | connsm->conn_handle; htole16(rxbuf, acl_hdr); htole16(rxbuf + 2, acl_len); - ble_hs_rx_data(rxpdu); + ble_hci_trans_ll_acl_tx(rxpdu); } /* NOTE: we dont free the mbuf since we handed it off! */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/src/ble_ll_conn_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_hci.c b/net/nimble/controller/src/ble_ll_conn_hci.c index 1d6102e..f653ca6 100644 --- a/net/nimble/controller/src/ble_ll_conn_hci.c +++ b/net/nimble/controller/src/ble_ll_conn_hci.c @@ -25,6 +25,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_conn.h" @@ -140,7 +141,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status) enh_enabled = ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE); if (enabled || enh_enabled) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { /* Put common elements in event */ evbuf[0] = BLE_HCI_EVCODE_LE_META; @@ -246,7 +247,7 @@ ble_ll_conn_num_comp_pkts_event_send(void) (connsm->completed_pkts || !STAILQ_EMPTY(&connsm->conn_txq))) { /* If no buffer, get one, If cant get one, leave. */ if (!evbuf) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (!evbuf) { break; } @@ -313,7 +314,7 @@ ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm) uint8_t *evbuf; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_AUTH_PYLD_TMO)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_AUTH_PYLD_TMO; evbuf[1] = sizeof(uint16_t); @@ -338,7 +339,7 @@ ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason) uint8_t *evbuf; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DISCONN_CMP)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_DISCONN_CMP; evbuf[1] = BLE_HCI_EVENT_DISCONN_COMPLETE_LEN; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/src/ble_ll_conn_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h index 218ecbc..b855b22 100644 --- a/net/nimble/controller/src/ble_ll_conn_priv.h +++ b/net/nimble/controller/src/ble_ll_conn_priv.h @@ -81,6 +81,9 @@ extern struct ble_ll_conn_free_list g_ble_ll_conn_free_list; /* Pointer to connection state machine we are trying to create */ extern struct ble_ll_conn_sm *g_ble_ll_conn_create_sm; +extern struct os_mempool g_ble_ll_hci_ev_pool; + + /* Generic interface */ struct ble_ll_len_req; struct hci_create_conn; @@ -150,4 +153,8 @@ void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm); #else #define ble_ll_conn_auth_pyld_timer_start(x) #endif + +int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg); +int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg); + #endif /* H_BLE_LL_CONN_PRIV_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/src/ble_ll_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c index 2889367..352dda2 100644 --- a/net/nimble/controller/src/ble_ll_hci.c +++ b/net/nimble/controller/src/ble_ll_hci.c @@ -23,7 +23,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "controller/ble_hw.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" @@ -68,7 +68,7 @@ ble_ll_hci_event_send(uint8_t *evbuf) STATS_INC(ble_ll_stats, hci_events_sent); /* Send the event to the host */ - rc = ble_hci_transport_ctlr_event_send(evbuf); + rc = ble_hci_trans_ll_evt_tx(evbuf); return rc; } @@ -86,7 +86,7 @@ ble_ll_hci_send_noop(void) uint8_t *evbuf; uint16_t opcode; - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { /* Create a command complete event with a NO-OP opcode */ opcode = 0; @@ -919,7 +919,7 @@ ble_ll_hci_cmd_proc(struct os_event *ev) assert(cmdbuf != NULL); /* Free the event */ - err = os_memblock_put(&g_hci_os_event_pool, ev); + err = os_memblock_put(&g_ble_ll_hci_ev_pool, ev); assert(err == OS_OK); /* Get the opcode from the command buffer */ @@ -994,12 +994,12 @@ ble_ll_hci_cmd_proc(struct os_event *ev) * BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion. */ int -ble_hci_transport_host_cmd_send(uint8_t *cmd) +ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg) { struct os_event *ev; /* Get an event structure off the queue */ - ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool); + ev = (struct os_event *)os_memblock_get(&g_ble_ll_hci_ev_pool); if (!ev) { return BLE_ERR_MEM_CAPACITY; } @@ -1015,7 +1015,7 @@ ble_hci_transport_host_cmd_send(uint8_t *cmd) /* Send ACL data from host to contoller */ int -ble_hci_transport_host_acl_data_send(struct os_mbuf *om) +ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg) { ble_ll_acl_data_in(om); return 0; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/controller/src/ble_ll_hci_ev.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci_ev.c b/net/nimble/controller/src/ble_ll_hci_ev.c index 5624c65..2548bdc 100644 --- a/net/nimble/controller/src/ble_ll_hci_ev.c +++ b/net/nimble/controller/src/ble_ll_hci_ev.c @@ -21,6 +21,7 @@ #include <string.h> #include "nimble/ble.h" #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_ctrl.h" @@ -41,7 +42,7 @@ ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm) uint8_t *evbuf; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_DATA_LEN_CHG)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = BLE_HCI_LE_DATA_LEN_CHG_LEN; @@ -68,7 +69,7 @@ ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm, uint8_t *evbuf; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = BLE_HCI_LE_REM_CONN_PARM_REQ_LEN; @@ -95,7 +96,7 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status) uint8_t *evbuf; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = BLE_HCI_LE_CONN_UPD_LEN; @@ -127,7 +128,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) } if (ble_ll_hci_is_event_enabled(evcode)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = evcode; evbuf[1] = evlen; @@ -158,7 +159,7 @@ ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm *connsm) uint8_t *evbuf; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_LT_KEY_REQ)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = BLE_HCI_LE_LT_KEY_REQ_LEN; @@ -188,7 +189,7 @@ ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm *connsm, uint8_t status) uint8_t *evbuf; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = BLE_HCI_LE_RD_REM_USED_FEAT_LEN; @@ -208,7 +209,7 @@ ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm *connsm, uint8_t status) uint8_t *evbuf; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP; evbuf[1] = BLE_HCI_EVENT_RD_RM_VER_LEN; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/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 c926846..64c3990 100644 --- a/net/nimble/controller/src/ble_ll_scan.c +++ b/net/nimble/controller/src/ble_ll_scan.c @@ -25,6 +25,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "controller/ble_phy.h" #include "controller/ble_hw.h" #include "controller/ble_ll.h" @@ -424,7 +425,7 @@ ble_ll_hci_send_adv_report(uint8_t pdu_type, uint8_t txadd, uint8_t *rxbuf, } if (ble_ll_hci_is_le_event_enabled(subev)) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); if (evbuf) { evbuf[0] = BLE_HCI_EVCODE_LE_META; evbuf[1] = event_len; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/include/host/ble_hs.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h index 5cdf863..faeaf14 100644 --- a/net/nimble/host/include/host/ble_hs.h +++ b/net/nimble/host/include/host/ble_hs.h @@ -21,6 +21,7 @@ #define H_BLE_HS_ #include <inttypes.h> +#include "nimble/hci_common.h" #include "host/ble_att.h" #include "host/ble_gap.h" #include "host/ble_gatt.h" @@ -62,6 +63,7 @@ struct os_event; #define BLE_HS_ETIMEOUT_HCI 19 #define BLE_HS_ENOMEM_EVT 20 #define BLE_HS_ENOADDR 21 +#define BLE_HS_ENOTSYNCED 22 #define BLE_HS_ERR_ATT_BASE 0x100 /* 256 */ #define BLE_HS_ATT_ERR(x) ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0) @@ -85,8 +87,10 @@ struct os_event; #define BLE_HS_IO_NO_INPUT_OUTPUT 0x03 #define BLE_HS_IO_KEYBOARD_DISPLAY 0x04 +typedef void ble_hs_reset_fn(int reason); +typedef void ble_hs_sync_fn(void); + struct ble_hs_cfg { - /*** HCI settings. */ /** * An HCI buffer is a "flat" 260-byte buffer. HCI buffers are used by the * controller to send unsolicited events to the host. @@ -105,6 +109,10 @@ struct ble_hs_cfg { * needs to be processsed. The pool of OS events is allocated with the * same number of elements as the HCI buffer pool. */ + /* XXX: This should either be renamed to indicate it is only used for OS + * events, or it should go away entirely (copy the number from the + * transport's config). + */ uint8_t max_hci_bufs; /*** Connection settings. */ @@ -211,6 +219,19 @@ struct ble_hs_cfg { uint8_t sm_our_key_dist; uint8_t sm_their_key_dist; + /*** HCI settings */ + /** + * This callback is executed when the host resets itself and the controller + * due to fatal error. + */ + ble_hs_reset_fn *reset_cb; + + /** + * This callback is executed when the host and controller become synced. + * This happens at startup and after a reset. + */ + ble_hs_sync_fn *sync_cb; + /*** Store settings. */ /** * These function callbacks handle persistence of sercurity material @@ -220,7 +241,7 @@ struct ble_hs_cfg { ble_store_write_fn *store_write_cb; ble_store_delete_fn *store_delete_cb; - /*** privacy settings */ + /*** Privacy settings. */ /** * The frequency at which new resovlable private addresses are generated. * Units are seconds. @@ -230,9 +251,8 @@ struct ble_hs_cfg { extern const struct ble_hs_cfg ble_hs_cfg_dflt; -int ble_hs_rx_data(struct os_mbuf *om); +int ble_hs_synced(void); int ble_hs_start(void); -void ble_hs_event_enqueue(struct os_event *ev); int ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/include/host/ble_hs_test.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_hs_test.h b/net/nimble/host/include/host/ble_hs_test.h index a883018..5d28291 100644 --- a/net/nimble/host/include/host/ble_hs_test.h +++ b/net/nimble/host/include/host/ble_hs_test.h @@ -23,9 +23,6 @@ #include <inttypes.h> struct os_mbuf; -void ble_hs_test_pkt_txed(struct os_mbuf *om); -void ble_hs_test_hci_txed(uint8_t *cmdbuf); - int ble_att_clt_test_all(void); int ble_att_svr_test_all(void); int ble_gap_test_all(void); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/include/host/host_hci.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h index dbe626a..79a0034 100644 --- a/net/nimble/host/include/host/host_hci.h +++ b/net/nimble/host/include/host/host_hci.h @@ -24,13 +24,7 @@ struct ble_hs_conn; struct os_mbuf; -#define HCI_CMD_BUF_SIZE 260 -#define HCI_EVT_BUF_SIZE 260 - -extern uint8_t host_hci_cmd_buf[HCI_CMD_BUF_SIZE]; - -int host_hci_os_event_proc(struct os_event *ev); -int host_hci_event_rx(uint8_t *data); +int host_hci_evt_process(uint8_t *data); uint16_t host_hci_opcode_join(uint8_t ogf, uint16_t ocf); void host_hci_write_hdr(uint8_t ogf, uint8_t ocf, uint8_t len, void *buf); int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/pkg.yml ---------------------------------------------------------------------- diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml index 0edea58..a45ba1e 100644 --- a/net/nimble/host/pkg.yml +++ b/net/nimble/host/pkg.yml @@ -36,20 +36,23 @@ pkg.deps: # Tinycrypt is only required when secure connections (NIMBPLE_OPT_SM_SC) # is enabled. It always gets built as a dependency, but not is not # included by the linker unless SC is enabled. XXX: We should not build - # this library if it is not requiresd. + # this library if it is not required. - libs/tinycrypt pkg.req_apis: + - ble_transport - console pkg.features: - BLE_HOST # Satisfy capability dependencies for the self-contained test executable. -pkg.deps.SELFTEST: libs/console/stub +pkg.deps.SELFTEST: + - libs/console/stub + - net/nimble/transport/ram + pkg.cflags.SELFTEST: - - -DPHONY_TRANSPORT=1 - - -DPHONY_HCI_ACKS=1 - - -DNIMBLE_OPT_SM=1 - - -DNIMBLE_OPT_SM_SC=1 + - "-DPHONY_HCI_ACKS=1" + - "-DNIMBLE_OPT_SM=1" + - "-DNIMBLE_OPT_SM_SC=1" pkg.cflags.TEST: -DBLE_HS_DEBUG http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_gap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c index a001ae3..1a41956 100644 --- a/net/nimble/host/src/ble_gap.c +++ b/net/nimble/host/src/ble_gap.c @@ -708,7 +708,7 @@ ble_gap_update_failed(uint16_t conn_handle, int status) ble_gap_update_notify(conn_handle, status); } -static void +void ble_gap_conn_broken(uint16_t conn_handle, int reason) { struct ble_gap_snapshot snap; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_gap_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap_priv.h b/net/nimble/host/src/ble_gap_priv.h index 449a4b0..3168d48 100644 --- a/net/nimble/host/src/ble_gap_priv.h +++ b/net/nimble/host/src/ble_gap_priv.h @@ -70,7 +70,6 @@ extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats; #define BLE_GAP_CONN_MODE_MAX 3 #define BLE_GAP_DISC_MODE_MAX 3 -int ble_gap_locked_by_cur_task(void); void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); int ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt); void ble_gap_rx_disconn_complete(struct hci_disconn_complete *evt); @@ -92,6 +91,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle, uint8_t prev_indicate, uint8_t cur_indicate); int ble_gap_master_in_progress(void); +void ble_gap_conn_broken(uint16_t conn_handle, int reason); int32_t ble_gap_heartbeat(void); int ble_gap_init(void); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hci_cmd.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hci_cmd.c b/net/nimble/host/src/ble_hci_cmd.c index 23eaba3..53fe726 100644 --- a/net/nimble/host/src/ble_hci_cmd.c +++ b/net/nimble/host/src/ble_hci_cmd.c @@ -21,6 +21,7 @@ #include <errno.h> #include <stdio.h> #include "os/os.h" +#include "nimble/ble_hci_trans.h" #include "ble_hs_priv.h" #include "host_dbg_priv.h" @@ -29,6 +30,8 @@ static struct os_mutex ble_hci_cmd_mutex; static struct os_sem ble_hci_cmd_sem; +static uint8_t *ble_hci_cmd_ack; + #if PHONY_HCI_ACKS static ble_hci_cmd_phony_ack_fn *ble_hci_cmd_phony_ack_cb; #endif @@ -69,7 +72,6 @@ ble_hci_cmd_rx_cmd_complete(uint8_t event_code, uint8_t *data, int len, uint8_t num_pkts; if (len < BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN) { - /* XXX: Increment stat. */ return BLE_HS_ECONTROLLER; } @@ -112,7 +114,6 @@ ble_hci_cmd_rx_cmd_status(uint8_t event_code, uint8_t *data, int len, uint8_t status; if (len < BLE_HCI_EVENT_CMD_STATUS_LEN) { - /* XXX: Increment stat. */ return BLE_HS_ECONTROLLER; } @@ -132,7 +133,8 @@ ble_hci_cmd_rx_cmd_status(uint8_t event_code, uint8_t *data, int len, } static int -ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len, +ble_hci_cmd_process_ack(uint16_t expected_opcode, + uint8_t *params_buf, uint8_t params_buf_len, struct ble_hci_ack *out_ack) { uint8_t event_code; @@ -140,20 +142,16 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len, uint8_t event_len; int rc; - /*** - * The controller always reuses the command buffer for its acknowledgement - * events. This function processes the acknowledgement event contained in - * the command buffer. - */ + BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL); /* Count events received */ STATS_INC(ble_hs_stats, hci_event); /* Display to console */ - host_hci_dbg_event_disp(host_hci_cmd_buf); + host_hci_dbg_event_disp(ble_hci_cmd_ack); - event_code = host_hci_cmd_buf[0]; - param_len = host_hci_cmd_buf[1]; + event_code = ble_hci_cmd_ack[0]; + param_len = ble_hci_cmd_ack[1]; event_len = param_len + 2; /* Clear ack fields up front to silence spurious gcc warnings. */ @@ -161,12 +159,12 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len, switch (event_code) { case BLE_HCI_EVCODE_COMMAND_COMPLETE: - rc = ble_hci_cmd_rx_cmd_complete(event_code, host_hci_cmd_buf, + rc = ble_hci_cmd_rx_cmd_complete(event_code, ble_hci_cmd_ack, event_len, out_ack); break; case BLE_HCI_EVCODE_COMMAND_STATUS: - rc = ble_hci_cmd_rx_cmd_status(event_code, host_hci_cmd_buf, + rc = ble_hci_cmd_rx_cmd_status(event_code, ble_hci_cmd_ack, event_len, out_ack); break; @@ -187,6 +185,14 @@ ble_hci_cmd_process_ack(uint8_t *params_buf, uint8_t params_buf_len, memcpy(params_buf, out_ack->bha_params, out_ack->bha_params_len); } out_ack->bha_params = params_buf; + + if (out_ack->bha_opcode != expected_opcode) { + rc = BLE_HS_ECONTROLLER; + } + } + + if (rc != 0) { + STATS_INC(ble_hs_stats, hci_invalid_ack); } return rc; @@ -201,15 +207,20 @@ ble_hci_cmd_wait_for_ack(void) if (ble_hci_cmd_phony_ack_cb == NULL) { rc = BLE_HS_ETIMEOUT_HCI; } else { - rc = ble_hci_cmd_phony_ack_cb(host_hci_cmd_buf, 260); + ble_hci_cmd_ack = + ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL); + rc = ble_hci_cmd_phony_ack_cb(ble_hci_cmd_ack, 260); } #else rc = os_sem_pend(&ble_hci_cmd_sem, BLE_HCI_CMD_TIMEOUT); switch (rc) { case 0: + BLE_HS_DBG_ASSERT(ble_hci_cmd_ack != NULL); break; case OS_TIMEOUT: rc = BLE_HS_ETIMEOUT_HCI; + STATS_INC(ble_hs_stats, hci_timeout); break; default: rc = BLE_HS_EOS; @@ -225,8 +236,12 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len, uint8_t *out_evt_buf_len) { struct ble_hci_ack ack; + uint16_t opcode; int rc; + opcode = le16toh((uint8_t *)cmd); + + BLE_HS_DBG_ASSERT(ble_hci_cmd_ack == NULL); ble_hci_cmd_lock(); rc = host_hci_cmd_send_buf(cmd); @@ -236,11 +251,13 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len, rc = ble_hci_cmd_wait_for_ack(); if (rc != 0) { + ble_hs_sched_reset(rc); goto done; } - rc = ble_hci_cmd_process_ack(evt_buf, evt_buf_len, &ack); + rc = ble_hci_cmd_process_ack(opcode, evt_buf, evt_buf_len, &ack); if (rc != 0) { + ble_hs_sched_reset(rc); goto done; } @@ -251,6 +268,11 @@ ble_hci_cmd_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len, rc = ack.bha_status; done: + if (ble_hci_cmd_ack != NULL) { + ble_hci_trans_buf_free(ble_hci_cmd_ack); + ble_hci_cmd_ack = NULL; + } + ble_hci_cmd_unlock(); return rc; } @@ -271,17 +293,17 @@ ble_hci_cmd_tx_empty_ack(void *cmd) void ble_hci_cmd_rx_ack(uint8_t *ack_ev) { - /* The controller should always reuse the command buffer for its acks. */ - BLE_HS_DBG_ASSERT(ack_ev == host_hci_cmd_buf); - if (ble_hci_cmd_sem.sem_tokens != 0) { /* This ack is unexpected; ignore it. */ + ble_hci_trans_buf_free(ack_ev); return; } + BLE_HS_DBG_ASSERT(ble_hci_cmd_ack == NULL); /* Unblock the application now that the HCI command buffer is populated * with the acknowledgement. */ + ble_hci_cmd_ack = ack_ev; os_sem_release(&ble_hci_cmd_sem); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c index aeba768..6e8a59f 100644 --- a/net/nimble/host/src/ble_hs.c +++ b/net/nimble/host/src/ble_hs.c @@ -23,12 +23,9 @@ #include "stats/stats.h" #include "util/tpq.h" #include "os/os.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "host/host_hci.h" #include "ble_hs_priv.h" -#ifdef PHONY_TRANSPORT -#include "host/ble_hs_test.h" -#endif /** * The maximum number of events the host will process in a row before returning @@ -38,27 +35,33 @@ static struct log_handler ble_hs_log_console_handler; -struct os_mempool g_hci_evt_pool; -static void *ble_hs_hci_evt_buf; - -/* XXX: this might be transport layer */ -#define HCI_OS_EVENT_BUF_SIZE (sizeof(struct os_event)) - -struct os_mempool g_hci_os_event_pool; +struct os_mempool ble_hs_hci_ev_pool; static void *ble_hs_hci_os_event_buf; +/** OS event - triggers tx of pending notifications and indications. */ static struct os_event ble_hs_event_tx_notifications = { .ev_type = BLE_HS_EVENT_TX_NOTIFICATIONS, .ev_arg = NULL, }; +/** OS event - triggers a full reset. */ +static struct os_event ble_hs_event_reset = { + .ev_type = BLE_HS_EVENT_RESET, + .ev_arg = NULL, +}; + +uint8_t ble_hs_sync_state; +static int ble_hs_reset_reason; + #if MYNEWT_SELFTEST /** Use a higher frequency timer to allow tests to run faster. */ -#define BLE_HS_HEARTBEAT_OS_TICKS (OS_TICKS_PER_SEC / 10) +#define BLE_HS_HEARTBEAT_OS_TICKS (OS_TICKS_PER_SEC / 10) #else -#define BLE_HS_HEARTBEAT_OS_TICKS OS_TICKS_PER_SEC +#define BLE_HS_HEARTBEAT_OS_TICKS OS_TICKS_PER_SEC #endif +#define BLE_HS_SYNC_RETRY_RATE (OS_TICKS_PER_SEC / 10) + /** * Handles unresponsive timeouts and periodic retries in case of resource * shortage. @@ -90,6 +93,9 @@ STATS_NAME_START(ble_hs_stats) STATS_NAME(ble_hs_stats, hci_event) STATS_NAME(ble_hs_stats, hci_invalid_ack) STATS_NAME(ble_hs_stats, hci_unknown_event) + STATS_NAME(ble_hs_stats, hci_timeout) + STATS_NAME(ble_hs_stats, reset) + STATS_NAME(ble_hs_stats, sync) STATS_NAME_END(ble_hs_stats) int @@ -157,11 +163,7 @@ ble_hs_process_tx_data_queue(void) struct os_mbuf *om; while ((om = os_mqueue_get(&ble_hs_tx_q)) != NULL) { -#ifdef PHONY_TRANSPORT - ble_hs_test_pkt_txed(om); -#else - ble_hci_transport_host_acl_data_send(om); -#endif + ble_hci_trans_hs_acl_tx(om); } } @@ -171,11 +173,22 @@ ble_hs_process_rx_data_queue(void) struct os_mbuf *om; while ((om = os_mqueue_get(&ble_hs_rx_q)) != NULL) { - host_hci_data_rx(om); + host_hci_acl_process(om); } } static void +ble_hs_clear_data_queue(struct os_mqueue *mqueue) +{ + struct os_mbuf *om; + + while ((om = os_mqueue_get(mqueue)) != NULL) { + os_mbuf_free_chain(om); + } +} + + +static void ble_hs_heartbeat_timer_reset(uint32_t ticks) { int rc; @@ -202,6 +215,85 @@ ble_hs_heartbeat_sched(int32_t ticks_from_now) } /** + * Indicates whether the host has synchronized with the controller. + * Synchronization must occur before any host procedures can be performed. + * + * @return 1 if the host and controller are in sync; + * 0 if the host and controller our out of sync. + */ +int +ble_hs_synced(void) +{ + return ble_hs_sync_state == BLE_HS_SYNC_STATE_GOOD; +} + +static int +ble_hs_sync(void) +{ + int rc; + + /* Set the sync state to "bringup." This allows the parent task to send + * the startup sequence to the controller. No other tasks are allowed to + * send any commands. + */ + ble_hs_sync_state = BLE_HS_SYNC_STATE_BRINGUP; + + rc = ble_hs_startup_go(); + if (rc == 0) { + ble_hs_sync_state = BLE_HS_SYNC_STATE_GOOD; + if (ble_hs_cfg.sync_cb != NULL) { + ble_hs_cfg.sync_cb(); + } + } else { + ble_hs_sync_state = BLE_HS_SYNC_STATE_BAD; + } + + ble_hs_heartbeat_sched(BLE_HS_SYNC_RETRY_RATE); + + if (rc == 0) { + STATS_INC(ble_hs_stats, sync); + } + + return rc; +} + +static int +ble_hs_reset(void) +{ + uint16_t conn_handle; + int rc; + + STATS_INC(ble_hs_stats, reset); + + ble_hs_sync_state = 0; + + rc = ble_hci_trans_reset(); + if (rc != 0) { + return rc; + } + + ble_hs_clear_data_queue(&ble_hs_tx_q); + ble_hs_clear_data_queue(&ble_hs_rx_q); + + while (1) { + conn_handle = ble_hs_atomic_first_conn_handle(); + if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { + break; + } + + ble_gap_conn_broken(conn_handle, ble_hs_reset_reason); + } + + if (ble_hs_cfg.reset_cb != NULL && ble_hs_reset_reason != 0) { + ble_hs_cfg.reset_cb(ble_hs_reset_reason); + } + ble_hs_reset_reason = 0; + + rc = ble_hs_sync(); + return rc; +} + +/** * Called once a second by the ble_hs heartbeat timer. Handles unresponsive * timeouts and periodic retries in case of resource shortage. */ @@ -210,6 +302,11 @@ ble_hs_heartbeat(void *unused) { int32_t ticks_until_next; + if (!ble_hs_sync_state) { + ble_hs_reset(); + return; + } + /* Ensure the timer expires at least once in the next second. * XXX: This is not very power efficient. We will need separate timers for * each module. @@ -235,7 +332,9 @@ ble_hs_event_handle(void *unused) { struct os_callout_func *cf; struct os_event *ev; + uint8_t *hci_evt; os_sr_t sr; + int rc; int i; i = 0; @@ -267,10 +366,15 @@ ble_hs_event_handle(void *unused) break; case BLE_HOST_HCI_EVENT_CTLR_EVENT: - host_hci_os_event_proc(ev); + hci_evt = ev->ev_arg; + rc = os_memblock_put(&ble_hs_hci_ev_pool, ev); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + host_hci_evt_process(hci_evt); break; case BLE_HS_EVENT_TX_NOTIFICATIONS: + BLE_HS_DBG_ASSERT(ev == &ble_hs_event_tx_notifications); ble_gatts_tx_notifications(); case OS_EVENT_T_MQUEUE_DATA: @@ -278,6 +382,11 @@ ble_hs_event_handle(void *unused) ble_hs_process_rx_data_queue(); break; + case BLE_HS_EVENT_RESET: + BLE_HS_DBG_ASSERT(ev == &ble_hs_event_reset); + ble_hs_reset(); + break; + default: BLE_HS_DBG_ASSERT(0); break; @@ -292,6 +401,22 @@ ble_hs_event_enqueue(struct os_event *ev) os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev); } +void +ble_hs_enqueue_hci_event(uint8_t *hci_evt) +{ + struct os_event *ev; + + ev = os_memblock_get(&ble_hs_hci_ev_pool); + if (ev == NULL) { + ble_hci_trans_buf_free(ev->ev_arg); + } else { + ev->ev_queued = 0; + ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT; + ev->ev_arg = hci_evt; + ble_hs_event_enqueue(ev); + } +} + /** * Schedules for all pending notifications and indications to be sent in the * host parent task. @@ -309,6 +434,15 @@ ble_hs_notifications_sched(void) ble_hs_event_enqueue(&ble_hs_event_tx_notifications); } +void +ble_hs_sched_reset(int reason) +{ + BLE_HS_DBG_ASSERT(ble_hs_reset_reason == 0); + + ble_hs_reset_reason = reason; + ble_hs_event_enqueue(&ble_hs_event_reset); +} + /** * Synchronizes the host with the controller by sending a sequence of HCI * commands. This function must be called before any other host functionality @@ -316,6 +450,10 @@ ble_hs_notifications_sched(void) * initialized. Typically, the host-parent-task calls this function at the top * of its task routine. * + * If the host fails to synchronize with the controller (if the controller is + * not fully booted, for example), the host will attempt to resynchronize every + * 100 ms. For this reason, an error return code is not necessarily fatal. + * * @return 0 on success; nonzero on error. */ int @@ -325,11 +463,9 @@ ble_hs_start(void) ble_hs_parent_task = os_sched_get_current_task(); - ble_hs_heartbeat_timer_reset(BLE_HS_HEARTBEAT_OS_TICKS); - ble_gatts_start(); - rc = ble_hs_startup_go(); + rc = ble_hs_sync(); return rc; } @@ -343,19 +479,18 @@ ble_hs_start(void) * @return 0 on success; nonzero on failure. */ int -ble_hs_rx_data(struct os_mbuf *om) +ble_hs_rx_data(struct os_mbuf *om, void *arg) { int rc; rc = os_mqueue_put(&ble_hs_rx_q, &ble_hs_evq, om); - if (rc != 0) { + if (rc == 0) { + os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev); + } else { os_mbuf_free_chain(om); - return BLE_HS_EOS; + rc = BLE_HS_EOS; } - - os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev); - - return 0; + return rc; } int @@ -375,9 +510,6 @@ ble_hs_tx_data(struct os_mbuf *om) static void ble_hs_free_mem(void) { - free(ble_hs_hci_evt_buf); - ble_hs_hci_evt_buf = NULL; - free(ble_hs_hci_os_event_buf); ble_hs_hci_os_event_buf = NULL; } @@ -418,30 +550,17 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg) log_console_handler_init(&ble_hs_log_console_handler); log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler); - ble_hs_hci_evt_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, - HCI_EVT_BUF_SIZE)); - if (ble_hs_hci_evt_buf == NULL) { - rc = BLE_HS_ENOMEM; - goto err; - } - - /* Create memory pool of command buffers */ - rc = os_mempool_init(&g_hci_evt_pool, ble_hs_cfg.max_hci_bufs, - HCI_EVT_BUF_SIZE, ble_hs_hci_evt_buf, - "HCICmdPool"); - assert(rc == 0); - - ble_hs_hci_os_event_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, - HCI_OS_EVENT_BUF_SIZE)); + ble_hs_hci_os_event_buf = malloc( + OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, sizeof (struct os_event))); if (ble_hs_hci_os_event_buf == NULL) { rc = BLE_HS_ENOMEM; goto err; } /* Create memory pool of OS events */ - rc = os_mempool_init(&g_hci_os_event_pool, ble_hs_cfg.max_hci_bufs, - HCI_OS_EVENT_BUF_SIZE, ble_hs_hci_os_event_buf, - "HCIOsEventPool"); + rc = os_mempool_init(&ble_hs_hci_ev_pool, ble_hs_cfg.max_hci_bufs, + sizeof (struct os_event), ble_hs_hci_os_event_buf, + "ble_hs_hci_ev_pool"); assert(rc == 0); /* Initialize eventq */ @@ -516,6 +635,9 @@ ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg) ble_hs_dbg_mutex_locked = 0; #endif + /* Configure the HCI transport to communicate with a host. */ + ble_hci_trans_cfg_hs(host_hci_evt_rx, NULL, ble_hs_rx_data, NULL); + return 0; err: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_atomic.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_atomic.c b/net/nimble/host/src/ble_hs_atomic.c index 36a603d..9c933fc 100644 --- a/net/nimble/host/src/ble_hs_atomic.c +++ b/net/nimble/host/src/ble_hs_atomic.c @@ -93,3 +93,23 @@ ble_hs_atomic_conn_set_flags(uint16_t conn_handle, ble_hs_conn_flags_t flags, return rc; } + +uint16_t +ble_hs_atomic_first_conn_handle(void) +{ + const struct ble_hs_conn *conn; + uint16_t conn_handle; + + ble_hs_lock(); + + conn = ble_hs_conn_first(); + if (conn != NULL) { + conn_handle = conn->bhc_handle; + } else { + conn_handle = BLE_HS_CONN_HANDLE_NONE; + } + + ble_hs_unlock(); + + return conn_handle; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_atomic_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_atomic_priv.h b/net/nimble/host/src/ble_hs_atomic_priv.h index a08b7ca..d82eeab 100644 --- a/net/nimble/host/src/ble_hs_atomic_priv.h +++ b/net/nimble/host/src/ble_hs_atomic_priv.h @@ -28,5 +28,6 @@ int ble_hs_atomic_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags); int ble_hs_atomic_conn_set_flags(uint16_t conn_handle, ble_hs_conn_flags_t flags, int on); +uint16_t ble_hs_atomic_first_conn_handle(void); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h index 79ef6b9..9e788dd 100644 --- a/net/nimble/host/src/ble_hs_priv.h +++ b/net/nimble/host/src/ble_hs_priv.h @@ -47,9 +47,15 @@ struct ble_hs_conn; struct ble_l2cap_chan; struct os_mbuf; struct os_mempool; +struct os_event; #define BLE_HOST_HCI_EVENT_CTLR_EVENT (OS_EVENT_T_PERUSER + 0) #define BLE_HS_EVENT_TX_NOTIFICATIONS (OS_EVENT_T_PERUSER + 1) +#define BLE_HS_EVENT_RESET (OS_EVENT_T_PERUSER + 2) + +#define BLE_HS_SYNC_STATE_BAD 0 +#define BLE_HS_SYNC_STATE_BRINGUP 1 +#define BLE_HS_SYNC_STATE_GOOD 2 STATS_SECT_START(ble_hs_stats) STATS_SECT_ENTRY(conn_create) @@ -58,17 +64,26 @@ STATS_SECT_START(ble_hs_stats) STATS_SECT_ENTRY(hci_event) STATS_SECT_ENTRY(hci_invalid_ack) STATS_SECT_ENTRY(hci_unknown_event) + STATS_SECT_ENTRY(hci_timeout) + STATS_SECT_ENTRY(reset) + STATS_SECT_ENTRY(sync) STATS_SECT_END extern STATS_SECT_DECL(ble_hs_stats) ble_hs_stats; extern struct ble_hs_cfg ble_hs_cfg; extern struct os_mbuf_pool ble_hs_mbuf_pool; +extern uint8_t ble_hs_sync_state; extern const uint8_t ble_hs_misc_null_addr[6]; void ble_hs_process_tx_data_queue(void); void ble_hs_process_rx_data_queue(void); int ble_hs_tx_data(struct os_mbuf *om); +void ble_hs_enqueue_hci_event(uint8_t *hci_evt); +void ble_hs_event_enqueue(struct os_event *ev); + +int host_hci_evt_rx(uint8_t *hci_ev, void *arg); +int host_hci_acl_process(struct os_mbuf *om); int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool, int num_entries, int entry_size, char *name); @@ -86,6 +101,7 @@ int ble_hs_locked_by_cur_task(void); int ble_hs_is_parent_task(void); void ble_hs_lock(void); void ble_hs_unlock(void); +void ble_hs_sched_reset(int reason); void ble_hs_heartbeat_sched(int32_t ticks); void ble_hs_notifications_sched(void); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_pvcy.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_pvcy.c b/net/nimble/host/src/ble_hs_pvcy.c index 05f9122..94a5586 100644 --- a/net/nimble/host/src/ble_hs_pvcy.c +++ b/net/nimble/host/src/ble_hs_pvcy.c @@ -145,11 +145,12 @@ ble_hs_pvcy_ensure_started(void) return 0; } -void +int ble_hs_pvcy_set_our_irk(const uint8_t *irk) { uint8_t tmp_addr[6]; uint8_t new_irk[16]; + int rc; memset(new_irk, 0, sizeof(new_irk)); @@ -163,17 +164,33 @@ ble_hs_pvcy_set_our_irk(const uint8_t *irk) if (memcmp(ble_hs_pvcy_irk, new_irk, 16) != 0) { memcpy(ble_hs_pvcy_irk, new_irk, 16); - ble_hs_pvcy_set_resolve_enabled(0); - ble_hs_pvcy_clear_entries(); - ble_hs_pvcy_set_resolve_enabled(1); + rc = ble_hs_pvcy_set_resolve_enabled(0); + if (rc != 0) { + return rc; + } + + rc = ble_hs_pvcy_clear_entries(); + if (rc != 0) { + return rc; + } + + rc = ble_hs_pvcy_set_resolve_enabled(1); + if (rc != 0) { + return rc; + } /* Push a null address identity to the controller. The controller uses * this entry to generate an RPA when we do advertising with * own-addr-type = rpa. */ memset(tmp_addr, 0, 6); - ble_hs_pvcy_add_entry(tmp_addr, 0, ble_hs_pvcy_irk); + rc = ble_hs_pvcy_add_entry(tmp_addr, 0, ble_hs_pvcy_irk); + if (rc != 0) { + return rc; + } } + + return 0; } int http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_pvcy_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_pvcy_priv.h b/net/nimble/host/src/ble_hs_pvcy_priv.h index 2635778..16ded35 100644 --- a/net/nimble/host/src/ble_hs_pvcy_priv.h +++ b/net/nimble/host/src/ble_hs_pvcy_priv.h @@ -22,7 +22,7 @@ #include <inttypes.h> -void ble_hs_pvcy_set_our_irk(const uint8_t *irk); +int ble_hs_pvcy_set_our_irk(const uint8_t *irk); int ble_hs_pvcy_our_irk(const uint8_t **out_irk); int ble_hs_pvcy_remove_entry(uint8_t addr_type, uint8_t *addr); int ble_hs_pvcy_add_entry(uint8_t *addr, uint8_t addrtype, uint8_t *irk); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/ble_hs_startup.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_startup.c b/net/nimble/host/src/ble_hs_startup.c index 45fb5ce..1ce49a7 100644 --- a/net/nimble/host/src/ble_hs_startup.c +++ b/net/nimble/host/src/ble_hs_startup.c @@ -222,19 +222,16 @@ ble_hs_startup_go(void) rc = ble_hs_startup_set_evmask_tx(); if (rc != 0) { - assert(0); return rc; } rc = ble_hs_startup_le_set_evmask_tx(); if (rc != 0) { - assert(0); return rc; } rc = ble_hs_startup_le_read_buf_sz_tx(); if (rc != 0) { - assert(0); return rc; } @@ -242,7 +239,6 @@ ble_hs_startup_go(void) rc = ble_hs_startup_le_read_sup_f_tx(); if (rc != 0) { - assert(0); return rc; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/host_dbg.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_dbg.c b/net/nimble/host/src/host_dbg.c index 6b58624..f5d46a3 100644 --- a/net/nimble/host/src/host_dbg.c +++ b/net/nimble/host/src/host_dbg.c @@ -23,7 +23,7 @@ #include "os/os.h" #include "console/console.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "ble_hs_priv.h" static void http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/host_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c index 791aec2..ed5dd6a 100644 --- a/net/nimble/host/src/host_hci.c +++ b/net/nimble/host/src/host_hci.c @@ -23,7 +23,7 @@ #include "os/os.h" #include "console/console.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "host/host_hci.h" #include "host/ble_gap.h" #include "ble_hs_priv.h" @@ -582,7 +582,7 @@ host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts) } int -host_hci_event_rx(uint8_t *data) +host_hci_evt_process(uint8_t *data) { const struct host_hci_event_dispatch_entry *entry; uint8_t event_code; @@ -604,40 +604,20 @@ host_hci_event_rx(uint8_t *data) entry = host_hci_dispatch_entry_find(event_code); if (entry == NULL) { - STATS_INC(ble_hs_stats, hci_invalid_ack); + STATS_INC(ble_hs_stats, hci_unknown_event); rc = BLE_HS_ENOTSUP; } else { rc = entry->hed_fn(event_code, data, event_len); } - return rc; -} - -int -host_hci_os_event_proc(struct os_event *ev) -{ - os_error_t err; - int rc; - - rc = host_hci_event_rx(ev->ev_arg); - - /* Free the command buffer */ - err = os_memblock_put(&g_hci_evt_pool, ev->ev_arg); - BLE_HS_DBG_ASSERT_EVAL(err == OS_OK); - - /* Free the event */ - err = os_memblock_put(&g_hci_os_event_pool, ev); - BLE_HS_DBG_ASSERT_EVAL(err == OS_OK); + ble_hci_trans_buf_free(data); return rc; } -/* XXX: For now, put this here */ int -ble_hci_transport_ctlr_event_send(uint8_t *hci_ev) +host_hci_evt_rx(uint8_t *hci_ev, void *arg) { - struct os_event *ev; - os_error_t err; int enqueue; BLE_HS_DBG_ASSERT(hci_ev != NULL); @@ -659,25 +639,12 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev) } if (enqueue) { - /* Get an event structure off the queue */ - ev = (struct os_event *)os_memblock_get(&g_hci_os_event_pool); - if (!ev) { - err = os_memblock_put(&g_hci_evt_pool, hci_ev); - BLE_HS_DBG_ASSERT_EVAL(err == OS_OK); - return -1; - } - - /* Fill out the event and post to host task. */ - ev->ev_queued = 0; - ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT; - ev->ev_arg = hci_ev; - ble_hs_event_enqueue(ev); + ble_hs_enqueue_hci_event(hci_ev); } return 0; } - /** * Called when a data packet is received from the controller. This function * consumes the supplied mbuf, regardless of the outcome. @@ -688,7 +655,7 @@ ble_hci_transport_ctlr_event_send(uint8_t *hci_ev) * @return 0 on success; nonzero on failure. */ int -host_hci_data_rx(struct os_mbuf *om) +host_hci_acl_process(struct os_mbuf *om) { struct hci_data_hdr hci_hdr; struct ble_hs_conn *conn; @@ -703,7 +670,7 @@ host_hci_data_rx(struct os_mbuf *om) } #if (BLETEST_THROUGHPUT_TEST == 0) - BLE_HS_LOG(DEBUG, "host_hci_data_rx(): handle=%u pb=%x len=%u data=", + BLE_HS_LOG(DEBUG, "host_hci_acl_process(): handle=%u pb=%x len=%u data=", BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc), BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc), hci_hdr.hdh_len); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/host_hci_cmd.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c index a3e021d..cce2e26 100644 --- a/net/nimble/host/src/host_hci_cmd.c +++ b/net/nimble/host/src/host_hci_cmd.c @@ -24,32 +24,17 @@ #include "os/os.h" #include "console/console.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "host/host_hci.h" #include "host_dbg_priv.h" #include "ble_hs_priv.h" -#ifdef PHONY_TRANSPORT -#include "host/ble_hs_test.h" -#endif - -/** - * This buffer holds one of the following: - * 1. The current outgoing HCI command. - * 2. The current incoming HCI acknowledgement (command complete or command - * status event). - */ -uint8_t host_hci_cmd_buf[HCI_EVT_BUF_SIZE]; static int host_hci_cmd_transport(uint8_t *cmdbuf) { -#ifdef PHONY_TRANSPORT - ble_hs_test_hci_txed(cmdbuf); - return 0; -#else int rc; - rc = ble_hci_transport_host_cmd_send(cmdbuf); + rc = ble_hci_trans_hs_cmd_tx(cmdbuf); switch (rc) { case 0: return 0; @@ -60,7 +45,6 @@ host_hci_cmd_transport(uint8_t *cmdbuf) default: return BLE_HS_EUNKNOWN; } -#endif } void @@ -79,19 +63,23 @@ host_hci_write_hdr(uint8_t ogf, uint8_t ocf, uint8_t len, void *buf) int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, const void *cmddata) { + uint8_t *buf; int rc; - htole16(host_hci_cmd_buf, ogf << 10 | ocf); - host_hci_cmd_buf[2] = len; + buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + BLE_HS_DBG_ASSERT(buf != NULL); + + htole16(buf, ogf << 10 | ocf); + buf[2] = len; if (len != 0) { - memcpy(host_hci_cmd_buf + BLE_HCI_CMD_HDR_LEN, cmddata, len); + memcpy(buf + BLE_HCI_CMD_HDR_LEN, cmddata, len); } BLE_HS_LOG(DEBUG, "host_hci_cmd_send: ogf=0x%02x ocf=0x%02x len=%d\n", ogf, ocf, len); - ble_hs_log_flat_buf(host_hci_cmd_buf, len + BLE_HCI_CMD_HDR_LEN); + ble_hs_log_flat_buf(buf, len + BLE_HCI_CMD_HDR_LEN); BLE_HS_LOG(DEBUG, "\n"); - rc = host_hci_cmd_transport(host_hci_cmd_buf); + rc = host_hci_cmd_transport(buf); if (rc == 0) { STATS_INC(ble_hs_stats, hci_cmd); @@ -110,6 +98,24 @@ host_hci_cmd_send_buf(void *buf) uint8_t len; int rc; + switch (ble_hs_sync_state) { + case BLE_HS_SYNC_STATE_BAD: + return BLE_HS_ENOTSYNCED; + + case BLE_HS_SYNC_STATE_BRINGUP: + if (!ble_hs_is_parent_task()) { + return BLE_HS_ENOTSYNCED; + } + break; + + case BLE_HS_SYNC_STATE_GOOD: + break; + + default: + BLE_HS_DBG_ASSERT(0); + return BLE_HS_EUNKNOWN; + } + u8ptr = buf; opcode = le16toh(u8ptr + 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_gap_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_gap_test.c b/net/nimble/host/src/test/ble_gap_test.c index faf62c3..2ae3354 100644 --- a/net/nimble/host/src/test/ble_gap_test.c +++ b/net/nimble/host/src/test/ble_gap_test.c @@ -1136,6 +1136,7 @@ TEST_CASE(ble_gap_test_case_conn_find) struct ble_gap_conn_desc desc; struct ble_hs_conn *conn; + uint8_t pub_addr[6]; int rc; /*** We are master; public addresses. */ @@ -1150,6 +1151,10 @@ TEST_CASE(ble_gap_test_case_conn_find) ble_gap_test_util_connect_cb, NULL); + + rc = ble_hs_id_copy_addr(BLE_ADDR_TYPE_PUBLIC, pub_addr, NULL); + TEST_ASSERT_FATAL(rc == 0); + rc = ble_gap_conn_find(8, &desc); TEST_ASSERT_FATAL(rc == 0); TEST_ASSERT(desc.conn_handle == 8); @@ -1157,8 +1162,8 @@ TEST_CASE(ble_gap_test_case_conn_find) TEST_ASSERT(desc.our_ota_addr_type == BLE_ADDR_TYPE_PUBLIC); TEST_ASSERT(desc.peer_ota_addr_type == BLE_ADDR_TYPE_PUBLIC); TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER); - TEST_ASSERT(memcmp(desc.our_ota_addr, g_dev_addr, 6) == 0); - TEST_ASSERT(memcmp(desc.our_id_addr, g_dev_addr, 6) == 0); + TEST_ASSERT(memcmp(desc.our_ota_addr, pub_addr, 6) == 0); + TEST_ASSERT(memcmp(desc.our_id_addr, pub_addr, 6) == 0); TEST_ASSERT(memcmp(desc.peer_ota_addr, ((uint8_t[6]){2,3,4,5,6,7}), 6) == 0); TEST_ASSERT(memcmp(desc.peer_id_addr, @@ -1203,7 +1208,7 @@ TEST_CASE(ble_gap_test_case_conn_find) TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER); TEST_ASSERT(memcmp(desc.our_ota_addr, ((uint8_t[6]){0x40,1,2,3,4,5}), 6) == 0); - TEST_ASSERT(memcmp(desc.our_id_addr, g_dev_addr, 6) == 0); + TEST_ASSERT(memcmp(desc.our_id_addr, pub_addr, 6) == 0); TEST_ASSERT(memcmp(desc.peer_ota_addr, ((uint8_t[6]){0x50,1,2,3,4,5}), 6) == 0); TEST_ASSERT(memcmp(desc.peer_id_addr, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_host_hci_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_host_hci_test.c b/net/nimble/host/src/test/ble_host_hci_test.c index a8e8d82..32c5cf4 100644 --- a/net/nimble/host/src/test/ble_host_hci_test.c +++ b/net/nimble/host/src/test/ble_host_hci_test.c @@ -21,6 +21,7 @@ #include <errno.h> #include <string.h> #include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" #include "host/host_hci.h" #include "host/ble_hs_test.h" #include "testutil/testutil.h" @@ -28,13 +29,16 @@ TEST_CASE(ble_host_hci_test_event_bad) { - uint8_t buf[2]; + uint8_t *buf; int rc; /*** Invalid event code. */ + buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + TEST_ASSERT_FATAL(buf != NULL); + buf[0] = 0xff; buf[1] = 0; - rc = host_hci_event_rx(buf); + rc = host_hci_evt_process(buf); TEST_ASSERT(rc == BLE_HS_ENOTSUP); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_hs_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_hs_test.c b/net/nimble/host/src/test/ble_hs_test.c index 16ae9b9..0b89bc9 100644 --- a/net/nimble/host/src/test/ble_hs_test.c +++ b/net/nimble/host/src/test/ble_hs_test.c @@ -23,22 +23,6 @@ #include "testutil/testutil.h" #include "ble_hs_test_util.h" -/* Our global device address. */ -uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = { 0x0a, 0x54, 0xab, 0x49, 0x7f, 0x06 }; - -void -ble_hs_test_pkt_txed(struct os_mbuf *om) -{ - ble_hs_test_util_prev_tx_enqueue(om); -} - -void -ble_hs_test_hci_txed(uint8_t *cmdbuf) -{ - ble_hs_test_util_enqueue_hci_tx(cmdbuf); - os_memblock_put(&g_hci_evt_pool, cmdbuf); -} - #ifdef MYNEWT_SELFTEST int http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_hs_test_util.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c index 1a6dd5e..831a077 100644 --- a/net/nimble/host/src/test/ble_hs_test_util.c +++ b/net/nimble/host/src/test/ble_hs_test_util.c @@ -23,12 +23,21 @@ #include "testutil/testutil.h" #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "host/ble_hs_adv.h" #include "host/ble_hs_id.h" #include "host/host_hci.h" +#include "transport/ram/ble_hci_ram.h" #include "ble_hs_test_util.h" +/* Our global device address. */ +uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; + +#define BLE_HS_TEST_UTIL_PUB_ADDR_VAL { 0x0a, 0x54, 0xab, 0x49, 0x7f, 0x06 } + +static const uint8_t ble_hs_test_util_pub_addr[BLE_DEV_ADDR_LEN] = + BLE_HS_TEST_UTIL_PUB_ADDR_VAL; + /** Use lots of small mbufs to ensure correct mbuf usage. */ #define BLE_HS_TEST_UTIL_NUM_MBUFS (100) #define BLE_HS_TEST_UTIL_BUF_SIZE OS_ALIGN(100, 4) @@ -246,13 +255,14 @@ ble_hs_test_util_rx_hci_evt(uint8_t *evt) TEST_ASSERT_FATAL(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN); if (os_started()) { - evbuf = os_memblock_get(&g_hci_evt_pool); + evbuf = ble_hci_trans_buf_alloc( + BLE_HCI_TRANS_BUF_EVT_LO); TEST_ASSERT_FATAL(evbuf != NULL); memcpy(evbuf, evt, totlen); - rc = ble_hci_transport_ctlr_event_send(evbuf); + rc = ble_hci_trans_ll_evt_tx(evbuf); } else { - rc = host_hci_event_rx(evt); + rc = host_hci_evt_process(evt); } TEST_ASSERT_FATAL(rc == 0); @@ -679,14 +689,6 @@ ble_hs_test_util_adv_start(uint8_t own_addr_type, if (adv_params->conn_mode != BLE_GAP_CONN_MODE_DIR) { acks[i] = (struct ble_hs_test_util_phony_ack) { - BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR), - ble_hs_test_util_exp_hci_status(i, fail_idx, fail_status), - { 0 }, - 1, - }; - i++; - - acks[i] = (struct ble_hs_test_util_phony_ack) { BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADV_DATA), ble_hs_test_util_exp_hci_status(i, fail_idx, fail_status), }; @@ -777,6 +779,35 @@ ble_hs_test_util_conn_update(uint16_t conn_handle, } int +ble_hs_test_util_set_our_irk(const uint8_t *irk, int fail_idx, + uint8_t hci_status) +{ + int rc; + + ble_hs_test_util_set_ack_seq(((struct ble_hs_test_util_phony_ack[]) { + { + BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADDR_RES_EN), + ble_hs_test_util_exp_hci_status(0, fail_idx, hci_status), + }, + { + BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_CLR_RESOLV_LIST), + ble_hs_test_util_exp_hci_status(1, fail_idx, hci_status), + }, + { + BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADDR_RES_EN), + ble_hs_test_util_exp_hci_status(2, fail_idx, hci_status), + }, + { + BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_ADD_RESOLV_LIST), + ble_hs_test_util_exp_hci_status(3, fail_idx, hci_status), + }, + })); + + rc = ble_hs_pvcy_set_our_irk(irk); + return rc; +} + +int ble_hs_test_util_security_initiate(uint16_t conn_handle, uint8_t hci_status) { int rc; @@ -906,7 +937,8 @@ ble_hs_test_util_set_startup_acks(void) { .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_BUF_SIZE), - .evt_params = { 0xff, 0xff, 1 }, + /* Use a very low buffer size (16) to test fragmentation. */ + .evt_params = { 0x10, 0x00, 0x20 }, .evt_params_len = 3, }, { @@ -916,6 +948,12 @@ ble_hs_test_util_set_startup_acks(void) .evt_params_len = 8, }, { + .opcode = host_hci_opcode_join(BLE_HCI_OGF_INFO_PARAMS, + BLE_HCI_OCF_IP_RD_BD_ADDR), + .evt_params = BLE_HS_TEST_UTIL_PUB_ADDR_VAL, + .evt_params_len = 6, + }, + { .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADDR_RES_EN), }, @@ -1279,9 +1317,25 @@ ble_hs_test_util_post_test(void *arg) ble_hs_test_util_assert_mbufs_freed(); } +static int +ble_hs_test_util_pkt_txed(struct os_mbuf *om, void *arg) +{ + ble_hs_test_util_prev_tx_enqueue(om); + return 0; +} + +static int +ble_hs_test_util_hci_txed(uint8_t *cmdbuf, void *arg) +{ + ble_hs_test_util_enqueue_hci_tx(cmdbuf); + ble_hci_trans_buf_free(cmdbuf); + return 0; +} + void ble_hs_test_util_init(void) { + struct ble_hci_ram_cfg hci_cfg; struct ble_hs_cfg cfg; int rc; @@ -1323,10 +1377,18 @@ ble_hs_test_util_init(void) ble_hci_set_phony_ack_cb(NULL); - ble_hs_test_util_prev_hci_tx_clear(); + ble_hci_trans_cfg_ll(ble_hs_test_util_hci_txed, NULL, + ble_hs_test_util_pkt_txed, NULL); - ble_hs_id_set_pub(g_dev_addr); + hci_cfg = ble_hci_ram_cfg_dflt; + hci_cfg.num_evt_bufs = cfg.max_hci_bufs; + rc = ble_hci_ram_init(&hci_cfg); + TEST_ASSERT_FATAL(rc == 0); + + ble_hs_test_util_set_startup_acks(); - /* Use a very low buffer size (16) to test fragmentation. */ - host_hci_set_buf_size(16, 64); + rc = ble_hs_start(); + TEST_ASSERT_FATAL(rc == 0); + + ble_hs_test_util_prev_hci_tx_clear(); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_hs_test_util.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h index 9c4b982..00b090f 100644 --- a/net/nimble/host/src/test/ble_hs_test_util.h +++ b/net/nimble/host/src/test/ble_hs_test_util.h @@ -106,6 +106,8 @@ int ble_hs_test_util_wl_set(struct ble_gap_white_entry *white_list, int ble_hs_test_util_conn_update(uint16_t conn_handle, struct ble_gap_upd_params *params, uint8_t hci_status); +int ble_hs_test_util_set_our_irk(const uint8_t *irk, int fail_idx, + uint8_t hci_status); int ble_hs_test_util_security_initiate(uint16_t conn_handle, uint8_t hci_status); int ble_hs_test_util_l2cap_rx_first_frag(uint16_t conn_handle, uint16_t cid, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_os_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_os_test.c b/net/nimble/host/src/test/ble_os_test.c index 1ab8e0a..e12e489 100644 --- a/net/nimble/host/src/test/ble_os_test.c +++ b/net/nimble/host/src/test/ble_os_test.c @@ -21,7 +21,7 @@ #include "os/os.h" #include "testutil/testutil.h" #include "nimble/hci_common.h" -#include "nimble/hci_transport.h" +#include "nimble/ble_hci_trans.h" #include "host/ble_hs_test.h" #include "host/ble_gap.h" #include "ble_hs_test_util.h" http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/host/src/test/ble_sm_test_util.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_sm_test_util.c b/net/nimble/host/src/test/ble_sm_test_util.c index 1c052fb..bdecde6 100644 --- a/net/nimble/host/src/test/ble_sm_test_util.c +++ b/net/nimble/host/src/test/ble_sm_test_util.c @@ -229,7 +229,7 @@ ble_sm_test_util_init_good(struct ble_sm_test_params *params, ble_sm_dbg_set_next_ediv(out_us->ediv); ble_sm_dbg_set_next_master_id_rand(out_us->rand_num); ble_sm_dbg_set_next_ltk(out_us->ltk); - ble_hs_pvcy_set_our_irk(out_us->id_info->irk); + ble_hs_test_util_set_our_irk(out_us->id_info->irk, 0, 0); ble_sm_dbg_set_next_csrk(out_us->sign_info->sig_key); if (out_us->public_key != NULL) { @@ -909,8 +909,20 @@ ble_sm_test_util_verify_tx_lt_key_req_neg_reply(uint16_t conn_handle) } static void -ble_sm_test_util_set_lt_key_req_reply_ack(uint8_t status, - uint16_t conn_handle) +ble_sm_test_util_set_lt_key_req_neg_reply_ack(uint8_t status, + uint16_t conn_handle) +{ + static uint8_t params[BLE_HCI_LT_KEY_REQ_NEG_REPLY_ACK_PARAM_LEN]; + + htole16(params, conn_handle); + ble_hs_test_util_set_ack_params( + host_hci_opcode_join(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY), + status, params, sizeof params); +} + +static void +ble_sm_test_util_set_lt_key_req_reply_ack(uint8_t status, uint16_t conn_handle) { static uint8_t params[BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN]; @@ -1303,7 +1315,7 @@ ble_sm_test_util_peer_bonding_bad(uint16_t ediv, uint64_t rand_num) TEST_ASSERT(ble_sm_dbg_num_procs() == 0); /* Receive a long term key request from the controller. */ - ble_sm_test_util_set_lt_key_req_reply_ack(0, 2); + ble_sm_test_util_set_lt_key_req_neg_reply_ack(0, 2); ble_sm_test_util_rx_lt_key_req(2, rand_num, ediv); TEST_ASSERT(!conn->bhc_sec_state.encrypted); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/include/nimble/ble.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/ble.h b/net/nimble/include/nimble/ble.h index f2041c8..4deb9f3 100644 --- a/net/nimble/include/nimble/ble.h +++ b/net/nimble/include/nimble/ble.h @@ -34,10 +34,6 @@ struct ble_encryption_block uint8_t cipher_text[BLE_ENC_BLOCK_SIZE]; }; -/* Shared command pool for transort between host and controller */ -extern struct os_mempool g_hci_evt_pool; -extern struct os_mempool g_hci_os_event_pool; - /* * BLE MBUF structure: * http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/include/nimble/ble_hci_trans.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/ble_hci_trans.h b/net/nimble/include/nimble/ble_hci_trans.h new file mode 100644 index 0000000..822da96 --- /dev/null +++ b/net/nimble/include/nimble/ble_hci_trans.h @@ -0,0 +1,152 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_HCI_TRANSPORT_ +#define H_HCI_TRANSPORT_ + +#include <inttypes.h> +struct os_mbuf; + +#define BLE_HCI_TRANS_CMD_SZ 260 + +/*** Type of buffers for holding commands and events. */ +/** + * Low-priority event (advertising reports). A request to allocate a + * high-priority event buffer may allocate one of these instead if no + * high-priority buffers are available. + */ +#define BLE_HCI_TRANS_BUF_EVT_LO 1 + +/* High-priority event (all events except advertising reports). */ +#define BLE_HCI_TRANS_BUF_EVT_HI 2 + +/* Host-to-controller command. */ +#define BLE_HCI_TRANS_BUF_CMD 3 + +/** Callback function types; executed when HCI packets are received. */ +typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); +typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); + +/** + * Sends an HCI event from the controller to the host. + * + * @param cmd The HCI event to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); + +/** + * Sends ACL data from controller to host. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_ll_acl_tx(struct os_mbuf *om); + +/** + * Sends an HCI command from the host to the controller. + * + * @param cmd The HCI command to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_hs_cmd_tx(uint8_t *cmd); + +/** + * Sends ACL data from host to controller. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_hs_acl_tx(struct os_mbuf *om); + +/** + * Allocates a flat buffer of the specified type. + * + * @param type The type of buffer to allocate; one of the + * BLE_HCI_TRANS_BUF_[...] constants. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +uint8_t *ble_hci_trans_buf_alloc(int type); + +/** + * Frees the specified flat buffer. The buffer must have been allocated via + * ble_hci_trans_buf_alloc(). + * + * @param buf The buffer to free. + */ +void ble_hci_trans_buf_free(uint8_t *buf); + +/** + * Configures the HCI transport to operate with a controller. The transport + * will execute specified callbacks upon receiving HCI packets from the host. + * + * @param cmd_cb The callback to execute upon receiving an HCI + * command. + * @param cmd_arg Optional argument to pass to the command + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +void ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, + void *cmd_arg, + ble_hci_trans_rx_acl_fn *acl_cb, + void *acl_arg); + +/** + * Configures the HCI transport to operate with a host. The transport will + * execute specified callbacks upon receiving HCI packets from the controller. + * + * @param cmd_cb The callback to execute upon receiving an HCI + * event. + * @param cmd_arg Optional argument to pass to the command + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +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); + +/** + * Resets the HCI module to a clean state. Frees all buffers and reinitializes + * the underlying transport. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_reset(void); + +#endif /* H_HCI_TRANSPORT_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/include/nimble/hci_transport.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/hci_transport.h b/net/nimble/include/nimble/hci_transport.h deleted file mode 100644 index 7de737c..0000000 --- a/net/nimble/include/nimble/hci_transport.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef H_HCI_TRANSPORT_ -#define H_HCI_TRANSPORT_ - -/* Send a HCI command from the host to the controller */ -int ble_hci_transport_host_cmd_send(uint8_t *cmd); - -/* Send a HCI event from the controller to the host */ -int ble_hci_transport_ctlr_event_send(uint8_t *hci_ev); - -/* Send ACL data from host to contoller */ -int ble_hci_transport_host_acl_data_send(struct os_mbuf *om); - -#endif /* H_HCI_TRANSPORT_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h ---------------------------------------------------------------------- diff --git a/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h b/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h new file mode 100644 index 0000000..1c5b58e --- /dev/null +++ b/net/nimble/transport/ram/include/transport/ram/ble_hci_ram.h @@ -0,0 +1,15 @@ +#ifndef H_BLE_HCI_RAM_ +#define H_BLE_HCI_RAM_ + +#include "nimble/ble_hci_trans.h" + +struct ble_hci_ram_cfg { + uint16_t num_evt_bufs; + uint16_t evt_buf_sz; +}; + +extern const struct ble_hci_ram_cfg ble_hci_ram_cfg_dflt; + +int ble_hci_ram_init(const struct ble_hci_ram_cfg *cfg); + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/transport/ram/pkg.yml ---------------------------------------------------------------------- diff --git a/net/nimble/transport/ram/pkg.yml b/net/nimble/transport/ram/pkg.yml new file mode 100644 index 0000000..a3524a1 --- /dev/null +++ b/net/nimble/transport/ram/pkg.yml @@ -0,0 +1,33 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: net/nimble/transport/ram +pkg.description: XXX +pkg.author: "Apache Mynewt <[email protected]>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + +pkg.deps: + - net/nimble + - libs/os + +pkg.apis: + - ble_transport http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/transport/ram/src/ble_hci_ram.c ---------------------------------------------------------------------- diff --git a/net/nimble/transport/ram/src/ble_hci_ram.c b/net/nimble/transport/ram/src/ble_hci_ram.c new file mode 100644 index 0000000..aac5eb1 --- /dev/null +++ b/net/nimble/transport/ram/src/ble_hci_ram.c @@ -0,0 +1,190 @@ +#include <assert.h> +#include <errno.h> +#include <stddef.h> +#include "os/os.h" +#include "nimble/ble_hci_trans.h" +#include "transport/ram/ble_hci_ram.h" + +/** Default configuration. */ +const struct ble_hci_ram_cfg ble_hci_ram_cfg_dflt = { + .num_evt_bufs = 3, + .evt_buf_sz = BLE_HCI_TRANS_CMD_SZ, +}; + +static ble_hci_trans_rx_cmd_fn *ble_hci_ram_rx_cmd_hs_cb; +static void *ble_hci_ram_rx_cmd_hs_arg; + +static ble_hci_trans_rx_cmd_fn *ble_hci_ram_rx_cmd_ll_cb; +static void *ble_hci_ram_rx_cmd_ll_arg; + +static ble_hci_trans_rx_acl_fn *ble_hci_ram_rx_acl_hs_cb; +static void *ble_hci_ram_rx_acl_hs_arg; + +static ble_hci_trans_rx_acl_fn *ble_hci_ram_rx_acl_ll_cb; +static void *ble_hci_ram_rx_acl_ll_arg; + +static struct os_mempool ble_hci_ram_evt_pool; +static void *ble_hci_ram_evt_buf; + +static uint8_t *ble_hci_ram_hs_cmd_buf; +static uint8_t ble_hci_ram_hs_cmd_buf_alloced; + +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_ram_rx_cmd_hs_cb = cmd_cb; + ble_hci_ram_rx_cmd_hs_arg = cmd_arg; + ble_hci_ram_rx_acl_hs_cb = acl_cb; + ble_hci_ram_rx_acl_hs_arg = acl_arg; +} + +void +ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, + void *cmd_arg, + ble_hci_trans_rx_acl_fn *acl_cb, + void *acl_arg) +{ + ble_hci_ram_rx_cmd_ll_cb = cmd_cb; + ble_hci_ram_rx_cmd_ll_arg = cmd_arg; + ble_hci_ram_rx_acl_ll_cb = acl_cb; + ble_hci_ram_rx_acl_ll_arg = acl_arg; +} + +int +ble_hci_trans_hs_cmd_tx(uint8_t *cmd) +{ + int rc; + + assert(ble_hci_ram_rx_cmd_ll_cb != NULL); + + rc = ble_hci_ram_rx_cmd_ll_cb(cmd, ble_hci_ram_rx_cmd_ll_arg); + return rc; +} + +int +ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) +{ + int rc; + + assert(ble_hci_ram_rx_cmd_hs_cb != NULL); + + rc = ble_hci_ram_rx_cmd_hs_cb(hci_ev, ble_hci_ram_rx_cmd_hs_arg); + return rc; +} + +int +ble_hci_trans_hs_acl_tx(struct os_mbuf *om) +{ + int rc; + + assert(ble_hci_ram_rx_acl_ll_cb != NULL); + + rc = ble_hci_ram_rx_acl_ll_cb(om, ble_hci_ram_rx_acl_ll_arg); + return rc; +} + +int +ble_hci_trans_ll_acl_tx(struct os_mbuf *om) +{ + int rc; + + assert(ble_hci_ram_rx_acl_hs_cb != NULL); + + rc = ble_hci_ram_rx_acl_hs_cb(om, ble_hci_ram_rx_acl_hs_arg); + return rc; +} + +uint8_t * +ble_hci_trans_buf_alloc(int type) +{ + uint8_t *buf; + + switch (type) { + case BLE_HCI_TRANS_BUF_EVT_LO: + case BLE_HCI_TRANS_BUF_EVT_HI: + buf = os_memblock_get(&ble_hci_ram_evt_pool); + break; + + case BLE_HCI_TRANS_BUF_CMD: + assert(!ble_hci_ram_hs_cmd_buf_alloced); + ble_hci_ram_hs_cmd_buf_alloced = 1; + buf = ble_hci_ram_hs_cmd_buf; + break; + + default: + assert(0); + buf = NULL; + } + + return buf; +} + +void +ble_hci_trans_buf_free(uint8_t *buf) +{ + int rc; + + if (buf == ble_hci_ram_hs_cmd_buf) { + assert(ble_hci_ram_hs_cmd_buf_alloced); + ble_hci_ram_hs_cmd_buf_alloced = 0; + } else { + rc = os_memblock_put(&ble_hci_ram_evt_pool, buf); + assert(rc == 0); + } +} + +static void +ble_hci_ram_free_mem(void) +{ + free(ble_hci_ram_evt_buf); + ble_hci_ram_evt_buf = NULL; + + free(ble_hci_ram_hs_cmd_buf); + ble_hci_ram_hs_cmd_buf = NULL; + ble_hci_ram_hs_cmd_buf_alloced = 0; +} + +int +ble_hci_trans_reset(void) +{ + return 0; +} + +int +ble_hci_ram_init(const struct ble_hci_ram_cfg *cfg) +{ + int rc; + + ble_hci_ram_free_mem(); + + ble_hci_ram_evt_buf = malloc(OS_MEMPOOL_BYTES(cfg->num_evt_bufs, + cfg->evt_buf_sz)); + if (ble_hci_ram_evt_buf == NULL) { + rc = ENOMEM; + goto err; + } + + /* Create memory pool of command buffers */ + rc = os_mempool_init(&ble_hci_ram_evt_pool, cfg->num_evt_bufs, + cfg->evt_buf_sz, ble_hci_ram_evt_buf, + "ble_hci_ram_evt_pool"); + if (rc != 0) { + rc = EINVAL; + goto err; + } + + ble_hci_ram_hs_cmd_buf = malloc(BLE_HCI_TRANS_CMD_SZ); + if (ble_hci_ram_hs_cmd_buf == NULL) { + rc = ENOMEM; + goto err; + } + + return 0; + +err: + ble_hci_ram_free_mem(); + return rc; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h ---------------------------------------------------------------------- diff --git a/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h b/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h new file mode 100644 index 0000000..1fbaa74 --- /dev/null +++ b/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h @@ -0,0 +1,19 @@ +#ifndef H_BLE_HCI_UART_ +#define H_BLE_HCI_UART_ + +struct ble_hci_uart_cfg { + uint32_t baud; + uint16_t num_evt_bufs; + uint16_t evt_buf_sz; + uint8_t uart_port; + uint8_t flow_ctrl; + uint8_t data_bits; + uint8_t stop_bits; + uint8_t parity; +}; + +extern const struct ble_hci_uart_cfg ble_hci_uart_cfg_dflt; + +int ble_hci_uart_init(const struct ble_hci_uart_cfg *cfg); + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/2444d8f6/net/nimble/transport/uart/pkg.yml ---------------------------------------------------------------------- diff --git a/net/nimble/transport/uart/pkg.yml b/net/nimble/transport/uart/pkg.yml new file mode 100644 index 0000000..cce429c --- /dev/null +++ b/net/nimble/transport/uart/pkg.yml @@ -0,0 +1,34 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: net/nimble/transport/uart +pkg.description: XXX +pkg.author: "Apache Mynewt <[email protected]>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + +pkg.deps: + - hw/hal + - libs/os + - net/nimble + +pkg.apis: + - ble_transport
